rulesync 3.32.0 → 3.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3513,6 +3513,12 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
3513
3513
 
3514
3514
  // src/features/mcp/copilot-mcp.ts
3515
3515
  import { join as join33 } from "path";
3516
+ function convertToCopilotFormat(mcpServers) {
3517
+ return { servers: mcpServers };
3518
+ }
3519
+ function convertFromCopilotFormat(copilotConfig) {
3520
+ return copilotConfig.servers ?? {};
3521
+ }
3516
3522
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
3517
3523
  json;
3518
3524
  constructor(params) {
@@ -3552,16 +3558,20 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
3552
3558
  rulesyncMcp,
3553
3559
  validate = true
3554
3560
  }) {
3561
+ const copilotConfig = convertToCopilotFormat(rulesyncMcp.getMcpServers());
3555
3562
  return new _CopilotMcp({
3556
3563
  baseDir,
3557
3564
  relativeDirPath: this.getSettablePaths().relativeDirPath,
3558
3565
  relativeFilePath: this.getSettablePaths().relativeFilePath,
3559
- fileContent: rulesyncMcp.getFileContent(),
3566
+ fileContent: JSON.stringify(copilotConfig, null, 2),
3560
3567
  validate
3561
3568
  });
3562
3569
  }
3563
3570
  toRulesyncMcp() {
3564
- return this.toRulesyncMcpDefault();
3571
+ const mcpServers = convertFromCopilotFormat(this.json);
3572
+ return this.toRulesyncMcpDefault({
3573
+ fileContent: JSON.stringify({ mcpServers }, null, 2)
3574
+ });
3565
3575
  }
3566
3576
  validate() {
3567
3577
  return { success: true, error: null };
@@ -3945,6 +3955,37 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
3945
3955
 
3946
3956
  // src/features/mcp/roo-mcp.ts
3947
3957
  import { join as join38 } from "path";
3958
+ function isRooMcpServers(value) {
3959
+ return value !== void 0 && value !== null && typeof value === "object";
3960
+ }
3961
+ function convertToRooFormat(mcpServers) {
3962
+ return Object.fromEntries(
3963
+ Object.entries(mcpServers).map(([serverName, serverConfig]) => {
3964
+ const converted = { ...serverConfig };
3965
+ if (serverConfig.type === "http") {
3966
+ converted.type = "streamable-http";
3967
+ }
3968
+ if (serverConfig.transport === "http") {
3969
+ converted.transport = "streamable-http";
3970
+ }
3971
+ return [serverName, converted];
3972
+ })
3973
+ );
3974
+ }
3975
+ function convertFromRooFormat(mcpServers) {
3976
+ return Object.fromEntries(
3977
+ Object.entries(mcpServers).map(([serverName, serverConfig]) => {
3978
+ const converted = { ...serverConfig };
3979
+ if (serverConfig.type === "streamable-http") {
3980
+ converted.type = "http";
3981
+ }
3982
+ if (serverConfig.transport === "streamable-http") {
3983
+ converted.transport = "http";
3984
+ }
3985
+ return [serverName, converted];
3986
+ })
3987
+ );
3988
+ }
3948
3989
  var RooMcp = class _RooMcp extends ToolMcp {
3949
3990
  json;
3950
3991
  constructor(params) {
@@ -3984,7 +4025,9 @@ var RooMcp = class _RooMcp extends ToolMcp {
3984
4025
  rulesyncMcp,
3985
4026
  validate = true
3986
4027
  }) {
3987
- const fileContent = rulesyncMcp.getFileContent();
4028
+ const mcpServers = rulesyncMcp.getMcpServers();
4029
+ const convertedMcpServers = convertToRooFormat(mcpServers);
4030
+ const fileContent = JSON.stringify({ mcpServers: convertedMcpServers }, null, 2);
3988
4031
  return new _RooMcp({
3989
4032
  baseDir,
3990
4033
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -3994,7 +4037,11 @@ var RooMcp = class _RooMcp extends ToolMcp {
3994
4037
  });
3995
4038
  }
3996
4039
  toRulesyncMcp() {
3997
- return this.toRulesyncMcpDefault();
4040
+ const rawMcpServers = isRooMcpServers(this.json.mcpServers) ? this.json.mcpServers : {};
4041
+ const convertedMcpServers = convertFromRooFormat(rawMcpServers);
4042
+ return this.toRulesyncMcpDefault({
4043
+ fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
4044
+ });
3998
4045
  }
3999
4046
  validate() {
4000
4047
  return { success: true, error: null };
@@ -4239,17 +4286,19 @@ import { basename as basename21, join as join82 } from "path";
4239
4286
  import { encode } from "@toon-format/toon";
4240
4287
  import { z as z33 } from "zod/mini";
4241
4288
 
4242
- // src/features/skills/codexcli-skill.ts
4243
- import { join as join42 } from "path";
4244
- import { z as z20 } from "zod/mini";
4245
-
4246
4289
  // src/constants/general.ts
4247
4290
  var SKILL_FILE_NAME = "SKILL.md";
4248
4291
 
4249
- // src/features/skills/rulesync-skill.ts
4250
- import { join as join40 } from "path";
4292
+ // src/features/skills/agentsmd-skill.ts
4293
+ import { join as join42 } from "path";
4294
+
4295
+ // src/features/skills/simulated-skill.ts
4296
+ import { join as join41 } from "path";
4251
4297
  import { z as z19 } from "zod/mini";
4252
4298
 
4299
+ // src/features/skills/tool-skill.ts
4300
+ import { join as join40 } from "path";
4301
+
4253
4302
  // src/types/ai-dir.ts
4254
4303
  import path2, { basename as basename14, join as join39, relative as relative3, resolve as resolve4 } from "path";
4255
4304
  var AiDir = class {
@@ -4362,113 +4411,7 @@ var AiDir = class {
4362
4411
  }
4363
4412
  };
4364
4413
 
4365
- // src/features/skills/rulesync-skill.ts
4366
- var RulesyncSkillFrontmatterSchemaInternal = z19.object({
4367
- name: z19.string(),
4368
- description: z19.string(),
4369
- targets: z19._default(RulesyncTargetsSchema, ["*"]),
4370
- claudecode: z19.optional(
4371
- z19.object({
4372
- "allowed-tools": z19.optional(z19.array(z19.string()))
4373
- })
4374
- )
4375
- });
4376
- var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
4377
- var RulesyncSkill = class _RulesyncSkill extends AiDir {
4378
- constructor({
4379
- baseDir = process.cwd(),
4380
- relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4381
- dirName,
4382
- frontmatter,
4383
- body,
4384
- otherFiles = [],
4385
- validate = true,
4386
- global = false
4387
- }) {
4388
- super({
4389
- baseDir,
4390
- relativeDirPath,
4391
- dirName,
4392
- mainFile: {
4393
- name: SKILL_FILE_NAME,
4394
- body,
4395
- frontmatter: { ...frontmatter }
4396
- },
4397
- otherFiles,
4398
- global
4399
- });
4400
- if (validate) {
4401
- const result = this.validate();
4402
- if (!result.success) {
4403
- throw result.error;
4404
- }
4405
- }
4406
- }
4407
- static getSettablePaths() {
4408
- return {
4409
- relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
4410
- };
4411
- }
4412
- getFrontmatter() {
4413
- if (!this.mainFile?.frontmatter) {
4414
- throw new Error("Frontmatter is not defined");
4415
- }
4416
- const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4417
- return result;
4418
- }
4419
- getBody() {
4420
- return this.mainFile?.body ?? "";
4421
- }
4422
- validate() {
4423
- const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
4424
- if (!result.success) {
4425
- return {
4426
- success: false,
4427
- error: new Error(
4428
- `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4429
- )
4430
- };
4431
- }
4432
- return { success: true, error: null };
4433
- }
4434
- static async fromDir({
4435
- baseDir = process.cwd(),
4436
- relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4437
- dirName,
4438
- global = false
4439
- }) {
4440
- const skillDirPath = join40(baseDir, relativeDirPath, dirName);
4441
- const skillFilePath = join40(skillDirPath, SKILL_FILE_NAME);
4442
- if (!await fileExists(skillFilePath)) {
4443
- throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4444
- }
4445
- const fileContent = await readFileContent(skillFilePath);
4446
- const { frontmatter, body: content } = parseFrontmatter(fileContent);
4447
- const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
4448
- if (!result.success) {
4449
- throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4450
- }
4451
- const otherFiles = await this.collectOtherFiles(
4452
- baseDir,
4453
- relativeDirPath,
4454
- dirName,
4455
- SKILL_FILE_NAME
4456
- );
4457
- return new _RulesyncSkill({
4458
- baseDir,
4459
- relativeDirPath,
4460
- dirName,
4461
- frontmatter: result.data,
4462
- body: content.trim(),
4463
- otherFiles,
4464
- validate: true,
4465
- global
4466
- });
4467
- }
4468
- };
4469
-
4470
4414
  // src/features/skills/tool-skill.ts
4471
- import { join as join41 } from "path";
4472
4415
  var ToolSkill = class extends AiDir {
4473
4416
  /**
4474
4417
  * Get the settable paths for this tool's skill directories.
@@ -4542,8 +4485,8 @@ var ToolSkill = class extends AiDir {
4542
4485
  }) {
4543
4486
  const settablePaths = getSettablePaths({ global });
4544
4487
  const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4545
- const skillDirPath = join41(baseDir, actualRelativeDirPath, dirName);
4546
- const skillFilePath = join41(skillDirPath, SKILL_FILE_NAME);
4488
+ const skillDirPath = join40(baseDir, actualRelativeDirPath, dirName);
4489
+ const skillFilePath = join40(skillDirPath, SKILL_FILE_NAME);
4547
4490
  if (!await fileExists(skillFilePath)) {
4548
4491
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4549
4492
  }
@@ -4567,21 +4510,22 @@ var ToolSkill = class extends AiDir {
4567
4510
  }
4568
4511
  };
4569
4512
 
4570
- // src/features/skills/codexcli-skill.ts
4571
- var CodexCliSkillFrontmatterSchema = z20.object({
4572
- name: z20.string(),
4573
- description: z20.string()
4513
+ // src/features/skills/simulated-skill.ts
4514
+ var SimulatedSkillFrontmatterSchema = z19.object({
4515
+ name: z19.string(),
4516
+ description: z19.string()
4574
4517
  });
4575
- var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4518
+ var SimulatedSkill = class extends ToolSkill {
4519
+ frontmatter;
4520
+ body;
4576
4521
  constructor({
4577
4522
  baseDir = process.cwd(),
4578
- relativeDirPath = join42(".codex", "skills"),
4523
+ relativeDirPath,
4579
4524
  dirName,
4580
4525
  frontmatter,
4581
4526
  body,
4582
4527
  otherFiles = [],
4583
- validate = true,
4584
- global = false
4528
+ validate = true
4585
4529
  }) {
4586
4530
  super({
4587
4531
  baseDir,
@@ -4593,42 +4537,37 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4593
4537
  frontmatter: { ...frontmatter }
4594
4538
  },
4595
4539
  otherFiles,
4596
- global
4540
+ global: false
4541
+ // Simulated skills are project mode only
4597
4542
  });
4598
4543
  if (validate) {
4599
- const result = this.validate();
4544
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4600
4545
  if (!result.success) {
4601
- throw result.error;
4546
+ throw new Error(
4547
+ `Invalid frontmatter in ${join41(relativeDirPath, dirName)}: ${formatError(result.error)}`
4548
+ );
4602
4549
  }
4603
4550
  }
4551
+ this.frontmatter = frontmatter;
4552
+ this.body = body;
4604
4553
  }
4605
- static getSettablePaths({ global = false } = {}) {
4606
- if (!global) {
4607
- throw new Error("CodexCliSkill only supports global mode. Please pass { global: true }.");
4608
- }
4609
- return {
4610
- relativeDirPath: join42(".codex", "skills")
4611
- };
4554
+ getBody() {
4555
+ return this.body;
4612
4556
  }
4613
4557
  getFrontmatter() {
4614
- if (!this.mainFile?.frontmatter) {
4615
- throw new Error("Frontmatter is not defined");
4616
- }
4617
- const result = CodexCliSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4618
- return result;
4558
+ return this.frontmatter;
4619
4559
  }
4620
- getBody() {
4621
- return this.mainFile?.body ?? "";
4560
+ toRulesyncSkill() {
4561
+ throw new Error("Not implemented because it is a SIMULATED skill.");
4622
4562
  }
4623
4563
  validate() {
4624
- if (!this.mainFile) {
4625
- return {
4626
- success: false,
4627
- error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
4628
- };
4564
+ if (!this.frontmatter) {
4565
+ return { success: true, error: null };
4629
4566
  }
4630
- const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
4631
- if (!result.success) {
4567
+ const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
4568
+ if (result.success) {
4569
+ return { success: true, error: null };
4570
+ } else {
4632
4571
  return {
4633
4572
  success: false,
4634
4573
  error: new Error(
@@ -4636,98 +4575,141 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4636
4575
  )
4637
4576
  };
4638
4577
  }
4639
- return { success: true, error: null };
4640
- }
4641
- toRulesyncSkill() {
4642
- const frontmatter = this.getFrontmatter();
4643
- const rulesyncFrontmatter = {
4644
- name: frontmatter.name,
4645
- description: frontmatter.description,
4646
- targets: ["*"]
4647
- };
4648
- return new RulesyncSkill({
4649
- baseDir: this.baseDir,
4650
- relativeDirPath: this.relativeDirPath,
4651
- dirName: this.getDirName(),
4652
- frontmatter: rulesyncFrontmatter,
4653
- body: this.getBody(),
4654
- otherFiles: this.getOtherFiles(),
4655
- validate: true,
4656
- global: this.global
4657
- });
4658
4578
  }
4659
- static fromRulesyncSkill({
4579
+ static fromRulesyncSkillDefault({
4660
4580
  rulesyncSkill,
4661
- validate = true,
4662
- global = false
4581
+ validate = true
4663
4582
  }) {
4664
- const settablePaths = _CodexCliSkill.getSettablePaths({ global });
4665
4583
  const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4666
- const codexFrontmatter = {
4584
+ const simulatedFrontmatter = {
4667
4585
  name: rulesyncFrontmatter.name,
4668
4586
  description: rulesyncFrontmatter.description
4669
4587
  };
4670
- return new _CodexCliSkill({
4588
+ return {
4671
4589
  baseDir: rulesyncSkill.getBaseDir(),
4672
- relativeDirPath: settablePaths.relativeDirPath,
4590
+ relativeDirPath: this.getSettablePaths().relativeDirPath,
4673
4591
  dirName: rulesyncSkill.getDirName(),
4674
- frontmatter: codexFrontmatter,
4592
+ frontmatter: simulatedFrontmatter,
4675
4593
  body: rulesyncSkill.getBody(),
4676
4594
  otherFiles: rulesyncSkill.getOtherFiles(),
4677
- validate,
4678
- global
4679
- });
4680
- }
4681
- static isTargetedByRulesyncSkill(rulesyncSkill) {
4682
- const targets = rulesyncSkill.getFrontmatter().targets;
4683
- return targets.includes("*") || targets.includes("codexcli");
4595
+ validate
4596
+ };
4684
4597
  }
4685
- static async fromDir(params) {
4686
- const loaded = await this.loadSkillDirContent({
4687
- ...params,
4688
- getSettablePaths: _CodexCliSkill.getSettablePaths
4689
- });
4690
- const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
4691
- if (!result.success) {
4692
- const skillDirPath = join42(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
4693
- throw new Error(
4694
- `Invalid frontmatter in ${join42(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
4695
- );
4598
+ static async fromDirDefault({
4599
+ baseDir = process.cwd(),
4600
+ relativeDirPath,
4601
+ dirName
4602
+ }) {
4603
+ const settablePaths = this.getSettablePaths();
4604
+ const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4605
+ const skillDirPath = join41(baseDir, actualRelativeDirPath, dirName);
4606
+ const skillFilePath = join41(skillDirPath, SKILL_FILE_NAME);
4607
+ if (!await fileExists(skillFilePath)) {
4608
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4696
4609
  }
4697
- return new _CodexCliSkill({
4698
- baseDir: loaded.baseDir,
4699
- relativeDirPath: loaded.relativeDirPath,
4700
- dirName: loaded.dirName,
4610
+ const fileContent = await readFileContent(skillFilePath);
4611
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
4612
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4613
+ if (!result.success) {
4614
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4615
+ }
4616
+ const otherFiles = await this.collectOtherFiles(
4617
+ baseDir,
4618
+ actualRelativeDirPath,
4619
+ dirName,
4620
+ SKILL_FILE_NAME
4621
+ );
4622
+ return {
4623
+ baseDir,
4624
+ relativeDirPath: actualRelativeDirPath,
4625
+ dirName,
4701
4626
  frontmatter: result.data,
4702
- body: loaded.body,
4703
- otherFiles: loaded.otherFiles,
4704
- validate: true,
4705
- global: loaded.global
4627
+ body: content.trim(),
4628
+ otherFiles,
4629
+ validate: true
4630
+ };
4631
+ }
4632
+ /**
4633
+ * Check if a RulesyncSkill should be converted to this simulated skill type.
4634
+ * Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
4635
+ */
4636
+ static isTargetedByRulesyncSkillDefault({
4637
+ rulesyncSkill,
4638
+ toolTarget
4639
+ }) {
4640
+ const frontmatter = rulesyncSkill.getFrontmatter();
4641
+ const targets = frontmatter.targets;
4642
+ if (targets.includes("*")) {
4643
+ return true;
4644
+ }
4645
+ return targets.includes(toolTarget);
4646
+ }
4647
+ /**
4648
+ * Get the settable paths for this tool's skill directories.
4649
+ * Must be implemented by concrete subclasses.
4650
+ */
4651
+ static getSettablePaths(_options) {
4652
+ throw new Error("Please implement this method in the subclass.");
4653
+ }
4654
+ };
4655
+
4656
+ // src/features/skills/agentsmd-skill.ts
4657
+ var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
4658
+ static getSettablePaths(options) {
4659
+ if (options?.global) {
4660
+ throw new Error("AgentsmdSkill does not support global mode.");
4661
+ }
4662
+ return {
4663
+ relativeDirPath: join42(".agents", "skills")
4664
+ };
4665
+ }
4666
+ static async fromDir(params) {
4667
+ const baseParams = await this.fromDirDefault(params);
4668
+ return new _AgentsmdSkill(baseParams);
4669
+ }
4670
+ static fromRulesyncSkill(params) {
4671
+ const baseParams = {
4672
+ ...this.fromRulesyncSkillDefault(params),
4673
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4674
+ };
4675
+ return new _AgentsmdSkill(baseParams);
4676
+ }
4677
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4678
+ return this.isTargetedByRulesyncSkillDefault({
4679
+ rulesyncSkill,
4680
+ toolTarget: "agentsmd"
4706
4681
  });
4707
4682
  }
4708
4683
  };
4709
4684
 
4710
- // src/features/skills/copilot-skill.ts
4685
+ // src/features/skills/codexcli-skill.ts
4711
4686
  import { join as join44 } from "path";
4687
+ import { z as z21 } from "zod/mini";
4712
4688
 
4713
- // src/features/skills/simulated-skill.ts
4689
+ // src/features/skills/rulesync-skill.ts
4714
4690
  import { join as join43 } from "path";
4715
- import { z as z21 } from "zod/mini";
4716
- var SimulatedSkillFrontmatterSchema = z21.object({
4717
- name: z21.string(),
4718
- description: z21.string()
4691
+ import { z as z20 } from "zod/mini";
4692
+ var RulesyncSkillFrontmatterSchemaInternal = z20.object({
4693
+ name: z20.string(),
4694
+ description: z20.string(),
4695
+ targets: z20._default(RulesyncTargetsSchema, ["*"]),
4696
+ claudecode: z20.optional(
4697
+ z20.object({
4698
+ "allowed-tools": z20.optional(z20.array(z20.string()))
4699
+ })
4700
+ )
4719
4701
  });
4720
- var SimulatedSkill = class extends ToolSkill {
4721
- frontmatter;
4722
- body;
4702
+ var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
4703
+ var RulesyncSkill = class _RulesyncSkill extends AiDir {
4723
4704
  constructor({
4724
4705
  baseDir = process.cwd(),
4725
- relativeDirPath,
4706
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4726
4707
  dirName,
4727
4708
  frontmatter,
4728
4709
  body,
4729
4710
  otherFiles = [],
4730
- validate = true
4711
+ validate = true,
4712
+ global = false
4731
4713
  }) {
4732
4714
  super({
4733
4715
  baseDir,
@@ -4739,37 +4721,33 @@ var SimulatedSkill = class extends ToolSkill {
4739
4721
  frontmatter: { ...frontmatter }
4740
4722
  },
4741
4723
  otherFiles,
4742
- global: false
4743
- // Simulated skills are project mode only
4724
+ global
4744
4725
  });
4745
4726
  if (validate) {
4746
- const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4727
+ const result = this.validate();
4747
4728
  if (!result.success) {
4748
- throw new Error(
4749
- `Invalid frontmatter in ${join43(relativeDirPath, dirName)}: ${formatError(result.error)}`
4750
- );
4729
+ throw result.error;
4751
4730
  }
4752
4731
  }
4753
- this.frontmatter = frontmatter;
4754
- this.body = body;
4755
4732
  }
4756
- getBody() {
4757
- return this.body;
4733
+ static getSettablePaths() {
4734
+ return {
4735
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
4736
+ };
4758
4737
  }
4759
4738
  getFrontmatter() {
4760
- return this.frontmatter;
4739
+ if (!this.mainFile?.frontmatter) {
4740
+ throw new Error("Frontmatter is not defined");
4741
+ }
4742
+ const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4743
+ return result;
4761
4744
  }
4762
- toRulesyncSkill() {
4763
- throw new Error("Not implemented because it is a SIMULATED skill.");
4745
+ getBody() {
4746
+ return this.mainFile?.body ?? "";
4764
4747
  }
4765
4748
  validate() {
4766
- if (!this.frontmatter) {
4767
- return { success: true, error: null };
4768
- }
4769
- const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
4770
- if (result.success) {
4771
- return { success: true, error: null };
4772
- } else {
4749
+ const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
4750
+ if (!result.success) {
4773
4751
  return {
4774
4752
  success: false,
4775
4753
  error: new Error(
@@ -4777,92 +4755,193 @@ var SimulatedSkill = class extends ToolSkill {
4777
4755
  )
4778
4756
  };
4779
4757
  }
4758
+ return { success: true, error: null };
4780
4759
  }
4781
- static fromRulesyncSkillDefault({
4782
- rulesyncSkill,
4783
- validate = true
4784
- }) {
4785
- const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4786
- const simulatedFrontmatter = {
4787
- name: rulesyncFrontmatter.name,
4788
- description: rulesyncFrontmatter.description
4789
- };
4790
- return {
4791
- baseDir: rulesyncSkill.getBaseDir(),
4792
- relativeDirPath: this.getSettablePaths().relativeDirPath,
4793
- dirName: rulesyncSkill.getDirName(),
4794
- frontmatter: simulatedFrontmatter,
4795
- body: rulesyncSkill.getBody(),
4796
- otherFiles: rulesyncSkill.getOtherFiles(),
4797
- validate
4798
- };
4799
- }
4800
- static async fromDirDefault({
4760
+ static async fromDir({
4801
4761
  baseDir = process.cwd(),
4802
- relativeDirPath,
4803
- dirName
4762
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4763
+ dirName,
4764
+ global = false
4804
4765
  }) {
4805
- const settablePaths = this.getSettablePaths();
4806
- const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4807
- const skillDirPath = join43(baseDir, actualRelativeDirPath, dirName);
4766
+ const skillDirPath = join43(baseDir, relativeDirPath, dirName);
4808
4767
  const skillFilePath = join43(skillDirPath, SKILL_FILE_NAME);
4809
4768
  if (!await fileExists(skillFilePath)) {
4810
4769
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4811
4770
  }
4812
4771
  const fileContent = await readFileContent(skillFilePath);
4813
4772
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4814
- const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4773
+ const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
4815
4774
  if (!result.success) {
4816
4775
  throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4817
4776
  }
4818
4777
  const otherFiles = await this.collectOtherFiles(
4819
4778
  baseDir,
4820
- actualRelativeDirPath,
4779
+ relativeDirPath,
4821
4780
  dirName,
4822
4781
  SKILL_FILE_NAME
4823
4782
  );
4824
- return {
4783
+ return new _RulesyncSkill({
4825
4784
  baseDir,
4826
- relativeDirPath: actualRelativeDirPath,
4785
+ relativeDirPath,
4827
4786
  dirName,
4828
4787
  frontmatter: result.data,
4829
4788
  body: content.trim(),
4830
4789
  otherFiles,
4831
- validate: true
4790
+ validate: true,
4791
+ global
4792
+ });
4793
+ }
4794
+ };
4795
+
4796
+ // src/features/skills/codexcli-skill.ts
4797
+ var CodexCliSkillFrontmatterSchema = z21.object({
4798
+ name: z21.string(),
4799
+ description: z21.string()
4800
+ });
4801
+ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4802
+ constructor({
4803
+ baseDir = process.cwd(),
4804
+ relativeDirPath = join44(".codex", "skills"),
4805
+ dirName,
4806
+ frontmatter,
4807
+ body,
4808
+ otherFiles = [],
4809
+ validate = true,
4810
+ global = false
4811
+ }) {
4812
+ super({
4813
+ baseDir,
4814
+ relativeDirPath,
4815
+ dirName,
4816
+ mainFile: {
4817
+ name: SKILL_FILE_NAME,
4818
+ body,
4819
+ frontmatter: { ...frontmatter }
4820
+ },
4821
+ otherFiles,
4822
+ global
4823
+ });
4824
+ if (validate) {
4825
+ const result = this.validate();
4826
+ if (!result.success) {
4827
+ throw result.error;
4828
+ }
4829
+ }
4830
+ }
4831
+ static getSettablePaths({ global = false } = {}) {
4832
+ if (!global) {
4833
+ throw new Error("CodexCliSkill only supports global mode. Please pass { global: true }.");
4834
+ }
4835
+ return {
4836
+ relativeDirPath: join44(".codex", "skills")
4832
4837
  };
4833
4838
  }
4834
- /**
4835
- * Check if a RulesyncSkill should be converted to this simulated skill type.
4836
- * Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
4837
- */
4838
- static isTargetedByRulesyncSkillDefault({
4839
+ getFrontmatter() {
4840
+ if (!this.mainFile?.frontmatter) {
4841
+ throw new Error("Frontmatter is not defined");
4842
+ }
4843
+ const result = CodexCliSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4844
+ return result;
4845
+ }
4846
+ getBody() {
4847
+ return this.mainFile?.body ?? "";
4848
+ }
4849
+ validate() {
4850
+ if (!this.mainFile) {
4851
+ return {
4852
+ success: false,
4853
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
4854
+ };
4855
+ }
4856
+ const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
4857
+ if (!result.success) {
4858
+ return {
4859
+ success: false,
4860
+ error: new Error(
4861
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4862
+ )
4863
+ };
4864
+ }
4865
+ return { success: true, error: null };
4866
+ }
4867
+ toRulesyncSkill() {
4868
+ const frontmatter = this.getFrontmatter();
4869
+ const rulesyncFrontmatter = {
4870
+ name: frontmatter.name,
4871
+ description: frontmatter.description,
4872
+ targets: ["*"]
4873
+ };
4874
+ return new RulesyncSkill({
4875
+ baseDir: this.baseDir,
4876
+ relativeDirPath: this.relativeDirPath,
4877
+ dirName: this.getDirName(),
4878
+ frontmatter: rulesyncFrontmatter,
4879
+ body: this.getBody(),
4880
+ otherFiles: this.getOtherFiles(),
4881
+ validate: true,
4882
+ global: this.global
4883
+ });
4884
+ }
4885
+ static fromRulesyncSkill({
4839
4886
  rulesyncSkill,
4840
- toolTarget
4887
+ validate = true,
4888
+ global = false
4841
4889
  }) {
4842
- const frontmatter = rulesyncSkill.getFrontmatter();
4843
- const targets = frontmatter.targets;
4844
- if (targets.includes("*")) {
4845
- return true;
4846
- }
4847
- return targets.includes(toolTarget);
4890
+ const settablePaths = _CodexCliSkill.getSettablePaths({ global });
4891
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4892
+ const codexFrontmatter = {
4893
+ name: rulesyncFrontmatter.name,
4894
+ description: rulesyncFrontmatter.description
4895
+ };
4896
+ return new _CodexCliSkill({
4897
+ baseDir: rulesyncSkill.getBaseDir(),
4898
+ relativeDirPath: settablePaths.relativeDirPath,
4899
+ dirName: rulesyncSkill.getDirName(),
4900
+ frontmatter: codexFrontmatter,
4901
+ body: rulesyncSkill.getBody(),
4902
+ otherFiles: rulesyncSkill.getOtherFiles(),
4903
+ validate,
4904
+ global
4905
+ });
4848
4906
  }
4849
- /**
4850
- * Get the settable paths for this tool's skill directories.
4851
- * Must be implemented by concrete subclasses.
4852
- */
4853
- static getSettablePaths(_options) {
4854
- throw new Error("Please implement this method in the subclass.");
4907
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4908
+ const targets = rulesyncSkill.getFrontmatter().targets;
4909
+ return targets.includes("*") || targets.includes("codexcli");
4910
+ }
4911
+ static async fromDir(params) {
4912
+ const loaded = await this.loadSkillDirContent({
4913
+ ...params,
4914
+ getSettablePaths: _CodexCliSkill.getSettablePaths
4915
+ });
4916
+ const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
4917
+ if (!result.success) {
4918
+ const skillDirPath = join44(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
4919
+ throw new Error(
4920
+ `Invalid frontmatter in ${join44(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
4921
+ );
4922
+ }
4923
+ return new _CodexCliSkill({
4924
+ baseDir: loaded.baseDir,
4925
+ relativeDirPath: loaded.relativeDirPath,
4926
+ dirName: loaded.dirName,
4927
+ frontmatter: result.data,
4928
+ body: loaded.body,
4929
+ otherFiles: loaded.otherFiles,
4930
+ validate: true,
4931
+ global: loaded.global
4932
+ });
4855
4933
  }
4856
4934
  };
4857
4935
 
4858
4936
  // src/features/skills/copilot-skill.ts
4937
+ import { join as join45 } from "path";
4859
4938
  var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
4860
4939
  static getSettablePaths(options) {
4861
4940
  if (options?.global) {
4862
4941
  throw new Error("CopilotSkill does not support global mode.");
4863
4942
  }
4864
4943
  return {
4865
- relativeDirPath: join44(".github", "skills")
4944
+ relativeDirPath: join45(".github", "skills")
4866
4945
  };
4867
4946
  }
4868
4947
  static async fromDir(params) {
@@ -4885,31 +4964,61 @@ var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
4885
4964
  };
4886
4965
 
4887
4966
  // src/features/skills/cursor-skill.ts
4888
- import { join as join45 } from "path";
4967
+ import { join as join46 } from "path";
4889
4968
  var CursorSkill = class _CursorSkill extends SimulatedSkill {
4890
4969
  static getSettablePaths(options) {
4891
4970
  if (options?.global) {
4892
- throw new Error("CursorSkill does not support global mode.");
4971
+ throw new Error("CursorSkill does not support global mode.");
4972
+ }
4973
+ return {
4974
+ relativeDirPath: join46(".cursor", "skills")
4975
+ };
4976
+ }
4977
+ static async fromDir(params) {
4978
+ const baseParams = await this.fromDirDefault(params);
4979
+ return new _CursorSkill(baseParams);
4980
+ }
4981
+ static fromRulesyncSkill(params) {
4982
+ const baseParams = {
4983
+ ...this.fromRulesyncSkillDefault(params),
4984
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4985
+ };
4986
+ return new _CursorSkill(baseParams);
4987
+ }
4988
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4989
+ return this.isTargetedByRulesyncSkillDefault({
4990
+ rulesyncSkill,
4991
+ toolTarget: "cursor"
4992
+ });
4993
+ }
4994
+ };
4995
+
4996
+ // src/features/skills/geminicli-skill.ts
4997
+ import { join as join47 } from "path";
4998
+ var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
4999
+ static getSettablePaths(options) {
5000
+ if (options?.global) {
5001
+ throw new Error("GeminiCliSkill does not support global mode.");
4893
5002
  }
4894
5003
  return {
4895
- relativeDirPath: join45(".cursor", "skills")
5004
+ relativeDirPath: join47(".gemini", "skills")
4896
5005
  };
4897
5006
  }
4898
5007
  static async fromDir(params) {
4899
5008
  const baseParams = await this.fromDirDefault(params);
4900
- return new _CursorSkill(baseParams);
5009
+ return new _GeminiCliSkill(baseParams);
4901
5010
  }
4902
5011
  static fromRulesyncSkill(params) {
4903
5012
  const baseParams = {
4904
5013
  ...this.fromRulesyncSkillDefault(params),
4905
5014
  relativeDirPath: this.getSettablePaths().relativeDirPath
4906
5015
  };
4907
- return new _CursorSkill(baseParams);
5016
+ return new _GeminiCliSkill(baseParams);
4908
5017
  }
4909
5018
  static isTargetedByRulesyncSkill(rulesyncSkill) {
4910
5019
  return this.isTargetedByRulesyncSkillDefault({
4911
5020
  rulesyncSkill,
4912
- toolTarget: "cursor"
5021
+ toolTarget: "geminicli"
4913
5022
  });
4914
5023
  }
4915
5024
  };
@@ -4919,7 +5028,7 @@ import { basename as basename15, join as join50 } from "path";
4919
5028
  import { z as z23 } from "zod/mini";
4920
5029
 
4921
5030
  // src/types/dir-feature-processor.ts
4922
- import { join as join46 } from "path";
5031
+ import { join as join48 } from "path";
4923
5032
  var DirFeatureProcessor = class {
4924
5033
  baseDir;
4925
5034
  constructor({ baseDir = process.cwd() }) {
@@ -4941,14 +5050,14 @@ var DirFeatureProcessor = class {
4941
5050
  await ensureDir(dirPath);
4942
5051
  const mainFile = aiDir.getMainFile();
4943
5052
  if (mainFile) {
4944
- const mainFilePath = join46(dirPath, mainFile.name);
5053
+ const mainFilePath = join48(dirPath, mainFile.name);
4945
5054
  const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter);
4946
5055
  const contentWithNewline = addTrailingNewline(content);
4947
5056
  await writeFileContent(mainFilePath, contentWithNewline);
4948
5057
  }
4949
5058
  const otherFiles = aiDir.getOtherFiles();
4950
5059
  for (const file of otherFiles) {
4951
- const filePath = join46(dirPath, file.relativeFilePathToDirPath);
5060
+ const filePath = join48(dirPath, file.relativeFilePathToDirPath);
4952
5061
  const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
4953
5062
  await writeFileContent(filePath, contentWithNewline);
4954
5063
  }
@@ -4962,38 +5071,8 @@ var DirFeatureProcessor = class {
4962
5071
  }
4963
5072
  };
4964
5073
 
4965
- // src/features/skills/agentsmd-skill.ts
4966
- import { join as join47 } from "path";
4967
- var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
4968
- static getSettablePaths(options) {
4969
- if (options?.global) {
4970
- throw new Error("AgentsmdSkill does not support global mode.");
4971
- }
4972
- return {
4973
- relativeDirPath: join47(".agents", "skills")
4974
- };
4975
- }
4976
- static async fromDir(params) {
4977
- const baseParams = await this.fromDirDefault(params);
4978
- return new _AgentsmdSkill(baseParams);
4979
- }
4980
- static fromRulesyncSkill(params) {
4981
- const baseParams = {
4982
- ...this.fromRulesyncSkillDefault(params),
4983
- relativeDirPath: this.getSettablePaths().relativeDirPath
4984
- };
4985
- return new _AgentsmdSkill(baseParams);
4986
- }
4987
- static isTargetedByRulesyncSkill(rulesyncSkill) {
4988
- return this.isTargetedByRulesyncSkillDefault({
4989
- rulesyncSkill,
4990
- toolTarget: "agentsmd"
4991
- });
4992
- }
4993
- };
4994
-
4995
5074
  // src/features/skills/claudecode-skill.ts
4996
- import { join as join48 } from "path";
5075
+ import { join as join49 } from "path";
4997
5076
  import { z as z22 } from "zod/mini";
4998
5077
  var ClaudecodeSkillFrontmatterSchema = z22.object({
4999
5078
  name: z22.string(),
@@ -5003,7 +5082,7 @@ var ClaudecodeSkillFrontmatterSchema = z22.object({
5003
5082
  var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5004
5083
  constructor({
5005
5084
  baseDir = process.cwd(),
5006
- relativeDirPath = join48(".claude", "skills"),
5085
+ relativeDirPath = join49(".claude", "skills"),
5007
5086
  dirName,
5008
5087
  frontmatter,
5009
5088
  body,
@@ -5034,7 +5113,7 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5034
5113
  global: _global = false
5035
5114
  } = {}) {
5036
5115
  return {
5037
- relativeDirPath: join48(".claude", "skills")
5116
+ relativeDirPath: join49(".claude", "skills")
5038
5117
  };
5039
5118
  }
5040
5119
  getFrontmatter() {
@@ -5121,9 +5200,9 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5121
5200
  });
5122
5201
  const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
5123
5202
  if (!result.success) {
5124
- const skillDirPath = join48(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
5203
+ const skillDirPath = join49(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
5125
5204
  throw new Error(
5126
- `Invalid frontmatter in ${join48(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
5205
+ `Invalid frontmatter in ${join49(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
5127
5206
  );
5128
5207
  }
5129
5208
  return new _ClaudecodeSkill({
@@ -5139,36 +5218,6 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5139
5218
  }
5140
5219
  };
5141
5220
 
5142
- // src/features/skills/geminicli-skill.ts
5143
- import { join as join49 } from "path";
5144
- var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
5145
- static getSettablePaths(options) {
5146
- if (options?.global) {
5147
- throw new Error("GeminiCliSkill does not support global mode.");
5148
- }
5149
- return {
5150
- relativeDirPath: join49(".gemini", "skills")
5151
- };
5152
- }
5153
- static async fromDir(params) {
5154
- const baseParams = await this.fromDirDefault(params);
5155
- return new _GeminiCliSkill(baseParams);
5156
- }
5157
- static fromRulesyncSkill(params) {
5158
- const baseParams = {
5159
- ...this.fromRulesyncSkillDefault(params),
5160
- relativeDirPath: this.getSettablePaths().relativeDirPath
5161
- };
5162
- return new _GeminiCliSkill(baseParams);
5163
- }
5164
- static isTargetedByRulesyncSkill(rulesyncSkill) {
5165
- return this.isTargetedByRulesyncSkillDefault({
5166
- rulesyncSkill,
5167
- toolTarget: "geminicli"
5168
- });
5169
- }
5170
- };
5171
-
5172
5221
  // src/features/skills/skills-processor.ts
5173
5222
  var skillsProcessorToolTargetTuple = [
5174
5223
  "agentsmd",
@@ -7982,33 +8031,196 @@ var rulesProcessorToolTargets = [
7982
8031
  "windsurf"
7983
8032
  ];
7984
8033
  var RulesProcessorToolTargetSchema = z33.enum(rulesProcessorToolTargets);
7985
- var rulesProcessorToolTargetsGlobal = [
7986
- "claudecode",
7987
- "claudecode-legacy",
7988
- "codexcli",
7989
- "geminicli"
7990
- ];
7991
8034
  var toolRuleFactories = /* @__PURE__ */ new Map([
7992
- ["agentsmd", { class: AgentsMdRule, meta: { extension: "md" } }],
7993
- ["amazonqcli", { class: AmazonQCliRule, meta: { extension: "md" } }],
7994
- ["antigravity", { class: AntigravityRule, meta: { extension: "md" } }],
7995
- ["augmentcode", { class: AugmentcodeRule, meta: { extension: "md" } }],
7996
- ["augmentcode-legacy", { class: AugmentcodeLegacyRule, meta: { extension: "md" } }],
7997
- ["claudecode", { class: ClaudecodeRule, meta: { extension: "md" } }],
7998
- ["claudecode-legacy", { class: ClaudecodeLegacyRule, meta: { extension: "md" } }],
7999
- ["cline", { class: ClineRule, meta: { extension: "md" } }],
8000
- ["codexcli", { class: CodexcliRule, meta: { extension: "md" } }],
8001
- ["copilot", { class: CopilotRule, meta: { extension: "md" } }],
8002
- ["cursor", { class: CursorRule, meta: { extension: "mdc" } }],
8003
- ["geminicli", { class: GeminiCliRule, meta: { extension: "md" } }],
8004
- ["junie", { class: JunieRule, meta: { extension: "md" } }],
8005
- ["kiro", { class: KiroRule, meta: { extension: "md" } }],
8006
- ["opencode", { class: OpenCodeRule, meta: { extension: "md" } }],
8007
- ["qwencode", { class: QwencodeRule, meta: { extension: "md" } }],
8008
- ["roo", { class: RooRule, meta: { extension: "md" } }],
8009
- ["warp", { class: WarpRule, meta: { extension: "md" } }],
8010
- ["windsurf", { class: WindsurfRule, meta: { extension: "md" } }]
8035
+ [
8036
+ "agentsmd",
8037
+ {
8038
+ class: AgentsMdRule,
8039
+ meta: {
8040
+ extension: "md",
8041
+ supportsGlobal: false,
8042
+ ruleDiscoveryMode: "toon",
8043
+ additionalConventions: {
8044
+ commands: { commandClass: AgentsmdCommand },
8045
+ subagents: { subagentClass: AgentsmdSubagent },
8046
+ skills: { skillClass: AgentsmdSkill }
8047
+ }
8048
+ }
8049
+ }
8050
+ ],
8051
+ [
8052
+ "amazonqcli",
8053
+ {
8054
+ class: AmazonQCliRule,
8055
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8056
+ }
8057
+ ],
8058
+ [
8059
+ "antigravity",
8060
+ {
8061
+ class: AntigravityRule,
8062
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8063
+ }
8064
+ ],
8065
+ [
8066
+ "augmentcode",
8067
+ {
8068
+ class: AugmentcodeRule,
8069
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8070
+ }
8071
+ ],
8072
+ [
8073
+ "augmentcode-legacy",
8074
+ {
8075
+ class: AugmentcodeLegacyRule,
8076
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8077
+ }
8078
+ ],
8079
+ [
8080
+ "claudecode",
8081
+ {
8082
+ class: ClaudecodeRule,
8083
+ meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "auto" }
8084
+ }
8085
+ ],
8086
+ [
8087
+ "claudecode-legacy",
8088
+ {
8089
+ class: ClaudecodeLegacyRule,
8090
+ meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "claudecode-legacy" }
8091
+ }
8092
+ ],
8093
+ [
8094
+ "cline",
8095
+ {
8096
+ class: ClineRule,
8097
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8098
+ }
8099
+ ],
8100
+ [
8101
+ "codexcli",
8102
+ {
8103
+ class: CodexcliRule,
8104
+ meta: {
8105
+ extension: "md",
8106
+ supportsGlobal: true,
8107
+ ruleDiscoveryMode: "toon",
8108
+ additionalConventions: {
8109
+ subagents: { subagentClass: CodexCliSubagent },
8110
+ skills: { skillClass: CodexCliSkill, globalOnly: true }
8111
+ }
8112
+ }
8113
+ }
8114
+ ],
8115
+ [
8116
+ "copilot",
8117
+ {
8118
+ class: CopilotRule,
8119
+ meta: {
8120
+ extension: "md",
8121
+ supportsGlobal: false,
8122
+ ruleDiscoveryMode: "auto",
8123
+ additionalConventions: {
8124
+ commands: { commandClass: CopilotCommand },
8125
+ subagents: { subagentClass: CopilotSubagent },
8126
+ skills: { skillClass: CopilotSkill }
8127
+ }
8128
+ }
8129
+ }
8130
+ ],
8131
+ [
8132
+ "cursor",
8133
+ {
8134
+ class: CursorRule,
8135
+ meta: {
8136
+ extension: "mdc",
8137
+ supportsGlobal: false,
8138
+ ruleDiscoveryMode: "auto",
8139
+ additionalConventions: {
8140
+ commands: { commandClass: CursorCommand },
8141
+ subagents: { subagentClass: CursorSubagent },
8142
+ skills: { skillClass: CursorSkill }
8143
+ },
8144
+ createsSeparateConventionsRule: true
8145
+ }
8146
+ }
8147
+ ],
8148
+ [
8149
+ "geminicli",
8150
+ {
8151
+ class: GeminiCliRule,
8152
+ meta: {
8153
+ extension: "md",
8154
+ supportsGlobal: true,
8155
+ ruleDiscoveryMode: "toon",
8156
+ additionalConventions: {
8157
+ commands: { commandClass: GeminiCliCommand },
8158
+ subagents: { subagentClass: GeminiCliSubagent },
8159
+ skills: { skillClass: GeminiCliSkill }
8160
+ }
8161
+ }
8162
+ }
8163
+ ],
8164
+ [
8165
+ "junie",
8166
+ {
8167
+ class: JunieRule,
8168
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8169
+ }
8170
+ ],
8171
+ [
8172
+ "kiro",
8173
+ {
8174
+ class: KiroRule,
8175
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8176
+ }
8177
+ ],
8178
+ [
8179
+ "opencode",
8180
+ {
8181
+ class: OpenCodeRule,
8182
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8183
+ }
8184
+ ],
8185
+ [
8186
+ "qwencode",
8187
+ {
8188
+ class: QwencodeRule,
8189
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8190
+ }
8191
+ ],
8192
+ [
8193
+ "roo",
8194
+ {
8195
+ class: RooRule,
8196
+ meta: {
8197
+ extension: "md",
8198
+ supportsGlobal: false,
8199
+ ruleDiscoveryMode: "auto",
8200
+ additionalConventions: {
8201
+ commands: { commandClass: RooCommand },
8202
+ subagents: { subagentClass: RooSubagent }
8203
+ },
8204
+ createsSeparateConventionsRule: true
8205
+ }
8206
+ }
8207
+ ],
8208
+ [
8209
+ "warp",
8210
+ {
8211
+ class: WarpRule,
8212
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8213
+ }
8214
+ ],
8215
+ [
8216
+ "windsurf",
8217
+ {
8218
+ class: WindsurfRule,
8219
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8220
+ }
8221
+ ]
8011
8222
  ]);
8223
+ var rulesProcessorToolTargetsGlobal = Array.from(toolRuleFactories.entries()).filter(([_, factory]) => factory.meta.supportsGlobal).map(([target]) => target);
8012
8224
  var defaultGetFactory6 = (target) => {
8013
8225
  const factory = toolRuleFactories.get(target);
8014
8226
  if (!factory) {
@@ -8023,6 +8235,7 @@ var RulesProcessor = class extends FeatureProcessor {
8023
8235
  simulateSkills;
8024
8236
  global;
8025
8237
  getFactory;
8238
+ skills;
8026
8239
  constructor({
8027
8240
  baseDir = process.cwd(),
8028
8241
  toolTarget,
@@ -8030,7 +8243,8 @@ var RulesProcessor = class extends FeatureProcessor {
8030
8243
  simulateSubagents = false,
8031
8244
  simulateSkills = false,
8032
8245
  global = false,
8033
- getFactory = defaultGetFactory6
8246
+ getFactory = defaultGetFactory6,
8247
+ skills
8034
8248
  }) {
8035
8249
  super({ baseDir });
8036
8250
  const result = RulesProcessorToolTargetSchema.safeParse(toolTarget);
@@ -8045,12 +8259,14 @@ var RulesProcessor = class extends FeatureProcessor {
8045
8259
  this.simulateSubagents = simulateSubagents;
8046
8260
  this.simulateSkills = simulateSkills;
8047
8261
  this.getFactory = getFactory;
8262
+ this.skills = skills;
8048
8263
  }
8049
8264
  async convertRulesyncFilesToToolFiles(rulesyncFiles) {
8050
8265
  const rulesyncRules = rulesyncFiles.filter(
8051
8266
  (file) => file instanceof RulesyncRule
8052
8267
  );
8053
8268
  const factory = this.getFactory(this.toolTarget);
8269
+ const { meta } = factory;
8054
8270
  const toolRules = rulesyncRules.map((rulesyncRule) => {
8055
8271
  if (!factory.class.isTargetedByRulesyncRule(rulesyncRule)) {
8056
8272
  return null;
@@ -8063,153 +8279,105 @@ var RulesProcessor = class extends FeatureProcessor {
8063
8279
  });
8064
8280
  }).filter((rule) => rule !== null);
8065
8281
  const isSimulated = this.simulateCommands || this.simulateSubagents || this.simulateSkills;
8066
- if (isSimulated && this.toolTarget === "cursor") {
8067
- toolRules.push(
8068
- new CursorRule({
8069
- baseDir: this.baseDir,
8070
- frontmatter: {
8071
- alwaysApply: true
8072
- },
8073
- body: this.generateAdditionalConventionsSection({
8074
- commands: { relativeDirPath: CursorCommand.getSettablePaths().relativeDirPath },
8075
- subagents: {
8076
- relativeDirPath: CursorSubagent.getSettablePaths().relativeDirPath
8077
- },
8078
- skills: {
8079
- relativeDirPath: CursorSkill.getSettablePaths().relativeDirPath
8080
- }
8081
- }),
8082
- relativeDirPath: CursorRule.getSettablePaths().nonRoot.relativeDirPath,
8083
- relativeFilePath: "additional-conventions.mdc",
8084
- validate: true
8085
- })
8086
- );
8087
- }
8088
- if (isSimulated && this.toolTarget === "roo") {
8089
- toolRules.push(
8090
- new RooRule({
8091
- baseDir: this.baseDir,
8092
- relativeDirPath: RooRule.getSettablePaths().nonRoot.relativeDirPath,
8093
- relativeFilePath: "additional-conventions.md",
8094
- fileContent: this.generateAdditionalConventionsSection({
8095
- commands: { relativeDirPath: RooCommand.getSettablePaths().relativeDirPath },
8096
- subagents: {
8097
- relativeDirPath: RooSubagent.getSettablePaths().relativeDirPath
8098
- }
8099
- }),
8100
- validate: true
8101
- })
8102
- );
8282
+ if (isSimulated && meta.createsSeparateConventionsRule && meta.additionalConventions) {
8283
+ const conventionsContent = this.generateAdditionalConventionsSectionFromMeta(meta);
8284
+ const settablePaths = factory.class.getSettablePaths();
8285
+ const nonRootPath = "nonRoot" in settablePaths ? settablePaths.nonRoot : null;
8286
+ if (nonRootPath) {
8287
+ toolRules.push(
8288
+ factory.class.fromRulesyncRule({
8289
+ baseDir: this.baseDir,
8290
+ rulesyncRule: new RulesyncRule({
8291
+ baseDir: this.baseDir,
8292
+ relativeDirPath: nonRootPath.relativeDirPath,
8293
+ relativeFilePath: "additional-conventions.md",
8294
+ frontmatter: {
8295
+ root: false,
8296
+ targets: [this.toolTarget]
8297
+ },
8298
+ body: conventionsContent
8299
+ }),
8300
+ validate: true,
8301
+ global: this.global
8302
+ })
8303
+ );
8304
+ }
8103
8305
  }
8104
8306
  const rootRuleIndex = toolRules.findIndex((rule) => rule.isRoot());
8105
8307
  if (rootRuleIndex === -1) {
8106
8308
  return toolRules;
8107
8309
  }
8108
- switch (this.toolTarget) {
8109
- case "agentsmd": {
8110
- const rootRule = toolRules[rootRuleIndex];
8111
- rootRule?.setFileContent(
8112
- this.generateToonReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
8113
- commands: { relativeDirPath: AgentsmdCommand.getSettablePaths().relativeDirPath },
8114
- subagents: {
8115
- relativeDirPath: AgentsmdSubagent.getSettablePaths().relativeDirPath
8116
- }
8117
- }) + rootRule.getFileContent()
8118
- );
8119
- return toolRules;
8120
- }
8121
- case "augmentcode-legacy": {
8122
- const rootRule = toolRules[rootRuleIndex];
8123
- rootRule?.setFileContent(
8124
- this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
8125
- );
8126
- return toolRules;
8127
- }
8128
- case "claudecode": {
8129
- return toolRules;
8130
- }
8131
- case "claudecode-legacy": {
8132
- const rootRule = toolRules[rootRuleIndex];
8133
- rootRule?.setFileContent(
8134
- this.generateReferencesSection(toolRules) + rootRule.getFileContent()
8135
- );
8136
- return toolRules;
8137
- }
8138
- case "codexcli": {
8139
- const rootRule = toolRules[rootRuleIndex];
8140
- rootRule?.setFileContent(
8141
- this.generateToonReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
8142
- subagents: {
8143
- relativeDirPath: CodexCliSubagent.getSettablePaths().relativeDirPath
8144
- },
8145
- // Codex CLI skills are only supported in global mode
8146
- ...this.global && {
8147
- skills: {
8148
- relativeDirPath: CodexCliSkill.getSettablePaths({ global: this.global }).relativeDirPath
8149
- }
8150
- }
8151
- }) + rootRule.getFileContent()
8152
- );
8153
- return toolRules;
8154
- }
8155
- case "copilot": {
8156
- const rootRule = toolRules[rootRuleIndex];
8157
- rootRule?.setFileContent(
8158
- this.generateAdditionalConventionsSection({
8159
- commands: { relativeDirPath: CopilotCommand.getSettablePaths().relativeDirPath },
8160
- subagents: {
8161
- relativeDirPath: CopilotSubagent.getSettablePaths().relativeDirPath
8162
- },
8163
- skills: {
8164
- relativeDirPath: CopilotSkill.getSettablePaths().relativeDirPath
8165
- }
8166
- }) + rootRule.getFileContent()
8167
- );
8168
- return toolRules;
8169
- }
8170
- case "geminicli": {
8171
- const rootRule = toolRules[rootRuleIndex];
8172
- rootRule?.setFileContent(
8173
- this.generateToonReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
8174
- commands: { relativeDirPath: GeminiCliCommand.getSettablePaths().relativeDirPath },
8175
- subagents: {
8176
- relativeDirPath: GeminiCliSubagent.getSettablePaths().relativeDirPath
8177
- }
8178
- }) + rootRule.getFileContent()
8179
- );
8180
- return toolRules;
8181
- }
8182
- case "kiro": {
8183
- const rootRule = toolRules[rootRuleIndex];
8184
- rootRule?.setFileContent(
8185
- this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
8186
- );
8187
- return toolRules;
8188
- }
8189
- case "opencode": {
8190
- const rootRule = toolRules[rootRuleIndex];
8191
- rootRule?.setFileContent(
8192
- this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
8193
- );
8194
- return toolRules;
8195
- }
8196
- case "qwencode": {
8197
- const rootRule = toolRules[rootRuleIndex];
8198
- rootRule?.setFileContent(
8199
- this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
8200
- );
8201
- return toolRules;
8202
- }
8203
- case "warp": {
8204
- const rootRule = toolRules[rootRuleIndex];
8205
- rootRule?.setFileContent(
8206
- this.generateToonReferencesSection(toolRules) + rootRule.getFileContent()
8207
- );
8208
- return toolRules;
8209
- }
8310
+ const rootRule = toolRules[rootRuleIndex];
8311
+ if (!rootRule) {
8312
+ return toolRules;
8313
+ }
8314
+ const referenceSection = this.generateReferenceSectionFromMeta(meta, toolRules);
8315
+ const conventionsSection = !meta.createsSeparateConventionsRule && meta.additionalConventions ? this.generateAdditionalConventionsSectionFromMeta(meta) : "";
8316
+ const newContent = referenceSection + conventionsSection + rootRule.getFileContent();
8317
+ rootRule.setFileContent(newContent);
8318
+ return toolRules;
8319
+ }
8320
+ buildSkillList(skillClass) {
8321
+ if (!this.skills) return [];
8322
+ const toolRelativeDirPath = skillClass.getSettablePaths({
8323
+ global: this.global
8324
+ }).relativeDirPath;
8325
+ return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
8326
+ const frontmatter = skill.getFrontmatter();
8327
+ const relativePath = join82(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
8328
+ return {
8329
+ name: frontmatter.name,
8330
+ description: frontmatter.description,
8331
+ path: relativePath
8332
+ };
8333
+ });
8334
+ }
8335
+ /**
8336
+ * Generate reference section based on meta configuration.
8337
+ */
8338
+ generateReferenceSectionFromMeta(meta, toolRules) {
8339
+ switch (meta.ruleDiscoveryMode) {
8340
+ case "toon":
8341
+ return this.generateToonReferencesSection(toolRules);
8342
+ case "claudecode-legacy":
8343
+ return this.generateReferencesSection(toolRules);
8344
+ case "auto":
8210
8345
  default:
8211
- return toolRules;
8346
+ return "";
8347
+ }
8348
+ }
8349
+ /**
8350
+ * Generate additional conventions section based on meta configuration.
8351
+ */
8352
+ generateAdditionalConventionsSectionFromMeta(meta) {
8353
+ const { additionalConventions } = meta;
8354
+ if (!additionalConventions) {
8355
+ return "";
8356
+ }
8357
+ const conventions = {};
8358
+ if (additionalConventions.commands) {
8359
+ const { commandClass } = additionalConventions.commands;
8360
+ const relativeDirPath = commandClass.getSettablePaths({
8361
+ global: this.global
8362
+ }).relativeDirPath;
8363
+ conventions.commands = { relativeDirPath };
8364
+ }
8365
+ if (additionalConventions.subagents) {
8366
+ const { subagentClass } = additionalConventions.subagents;
8367
+ const relativeDirPath = subagentClass.getSettablePaths({
8368
+ global: this.global
8369
+ }).relativeDirPath;
8370
+ conventions.subagents = { relativeDirPath };
8212
8371
  }
8372
+ if (additionalConventions.skills) {
8373
+ const { skillClass, globalOnly } = additionalConventions.skills;
8374
+ if (!globalOnly || this.global) {
8375
+ conventions.skills = {
8376
+ skillList: this.buildSkillList(skillClass)
8377
+ };
8378
+ }
8379
+ }
8380
+ return this.generateAdditionalConventionsSection(conventions);
8213
8381
  }
8214
8382
  async convertToolFilesToRulesyncFiles(toolFiles) {
8215
8383
  const toolRules = toolFiles.filter((file) => file instanceof ToolRule);
@@ -8394,15 +8562,7 @@ Simulated subagents are specialized AI assistants that can be invoked to handle
8394
8562
  When users call a simulated subagent, it will look for the corresponding markdown file, \`${join82(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
8395
8563
 
8396
8564
  For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join82(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
8397
- const skillsSection = skills ? `## Simulated Skills
8398
-
8399
- Simulated skills are specialized capabilities that can be invoked to handle specific types of tasks.
8400
-
8401
- When users invoke a simulated skill, look for the corresponding SKILL.md file in \`${join82(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "{skill}/SKILL.md")}\` and execute its contents as the block of operations.
8402
-
8403
- For example, if the user instructs \`Use the skill example-skill to achieve something\`, look for \`${join82(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "example-skill/SKILL.md")}\` and execute its contents.
8404
-
8405
- 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.` : "";
8565
+ const skillsSection = skills ? this.generateSkillsSection(skills) : "";
8406
8566
  const result = [
8407
8567
  overview,
8408
8568
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
@@ -8411,6 +8571,21 @@ Additionally, you should proactively consider using available skills when they w
8411
8571
  ].join("\n\n") + "\n\n";
8412
8572
  return result;
8413
8573
  }
8574
+ generateSkillsSection(skills) {
8575
+ if (!skills.skillList || skills.skillList.length === 0) {
8576
+ return "";
8577
+ }
8578
+ const skillListWithAtPrefix = skills.skillList.map((skill) => ({
8579
+ ...skill,
8580
+ path: `@${skill.path}`
8581
+ }));
8582
+ const toonContent = encode({ skillList: skillListWithAtPrefix });
8583
+ return `## Simulated Skills
8584
+
8585
+ Simulated skills are specialized capabilities that can be invoked to handle specific types of tasks. When you determine that a skill would be helpful for the current task, read the corresponding SKILL.md file and execute its instructions.
8586
+
8587
+ ${toonContent}`;
8588
+ }
8414
8589
  };
8415
8590
 
8416
8591
  // src/cli/commands/generate.ts
@@ -8423,13 +8598,15 @@ async function generateCommand(options) {
8423
8598
  process.exit(1);
8424
8599
  }
8425
8600
  logger.info(`Base directories: ${config.getBaseDirs().join(", ")}`);
8426
- const totalRulesOutputs = await generateRules(config);
8427
8601
  const totalIgnoreOutputs = await generateIgnore(config);
8428
8602
  const totalMcpOutputs = await generateMcp(config);
8429
8603
  const totalCommandOutputs = await generateCommands(config);
8430
8604
  const totalSubagentOutputs = await generateSubagents(config);
8431
- const totalSkillOutputs = await generateSkills(config);
8432
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
8605
+ const skillsResult = await generateSkills(config);
8606
+ const totalRulesOutputs = await generateRules(config, {
8607
+ skills: skillsResult.skills
8608
+ });
8609
+ const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + skillsResult.totalOutputs;
8433
8610
  if (totalGenerated === 0) {
8434
8611
  const enabledFeatures = config.getFeatures().join(", ");
8435
8612
  logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
@@ -8442,11 +8619,11 @@ async function generateCommand(options) {
8442
8619
  if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
8443
8620
  if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
8444
8621
  if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
8445
- if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
8622
+ if (skillsResult.totalOutputs > 0) parts.push(`${skillsResult.totalOutputs} skills`);
8446
8623
  logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
8447
8624
  }
8448
8625
  }
8449
- async function generateRules(config) {
8626
+ async function generateRules(config, options) {
8450
8627
  if (!config.getFeatures().includes("rules")) {
8451
8628
  logger.debug("Skipping rule generation (not in --features)");
8452
8629
  return 0;
@@ -8465,7 +8642,8 @@ async function generateRules(config) {
8465
8642
  global: config.getGlobal(),
8466
8643
  simulateCommands: config.getSimulateCommands(),
8467
8644
  simulateSubagents: config.getSimulateSubagents(),
8468
- simulateSkills: config.getSimulateSkills()
8645
+ simulateSkills: config.getSimulateSkills(),
8646
+ skills: options?.skills
8469
8647
  });
8470
8648
  if (config.getDelete()) {
8471
8649
  const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
@@ -8629,9 +8807,10 @@ async function generateSubagents(config) {
8629
8807
  async function generateSkills(config) {
8630
8808
  if (!config.getFeatures().includes("skills")) {
8631
8809
  logger.debug("Skipping skill generation (not in --features)");
8632
- return 0;
8810
+ return { totalOutputs: 0, skills: [] };
8633
8811
  }
8634
8812
  let totalSkillOutputs = 0;
8813
+ const allSkills = [];
8635
8814
  logger.info("Generating skill files...");
8636
8815
  const toolTargets = intersection(
8637
8816
  config.getTargets(),
@@ -8652,13 +8831,18 @@ async function generateSkills(config) {
8652
8831
  await processor.removeAiDirs(oldToolDirs);
8653
8832
  }
8654
8833
  const rulesyncDirs = await processor.loadRulesyncDirs();
8834
+ for (const rulesyncDir of rulesyncDirs) {
8835
+ if (rulesyncDir instanceof RulesyncSkill) {
8836
+ allSkills.push(rulesyncDir);
8837
+ }
8838
+ }
8655
8839
  const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
8656
8840
  const writtenCount = await processor.writeAiDirs(toolDirs);
8657
8841
  totalSkillOutputs += writtenCount;
8658
8842
  logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
8659
8843
  }
8660
8844
  }
8661
- return totalSkillOutputs;
8845
+ return { totalOutputs: totalSkillOutputs, skills: allSkills };
8662
8846
  }
8663
8847
 
8664
8848
  // src/cli/commands/gitignore.ts
@@ -10226,7 +10410,7 @@ async function mcpCommand({ version }) {
10226
10410
  }
10227
10411
 
10228
10412
  // src/cli/index.ts
10229
- var getVersion = () => "3.32.0";
10413
+ var getVersion = () => "3.33.0";
10230
10414
  var main = async () => {
10231
10415
  const program = new Command();
10232
10416
  const version = getVersion();