rulesync 3.32.0 → 3.34.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 +5 -0
  2. package/dist/index.cjs +1087 -627
  3. package/dist/index.js +1079 -619
  4. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ import { globSync } from "fs";
90
90
  import { mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
91
91
  import os from "os";
92
92
  import { basename, dirname, join, relative, resolve } from "path";
93
+ import { kebabCase } from "es-toolkit";
93
94
  async function ensureDir(dirPath) {
94
95
  try {
95
96
  await stat(dirPath);
@@ -217,6 +218,13 @@ function validateBaseDir(baseDir) {
217
218
  }
218
219
  checkPathTraversal({ relativePath: baseDir, intendedRootDir: process.cwd() });
219
220
  }
221
+ function toKebabCaseFilename(filename) {
222
+ const lastDotIndex = filename.lastIndexOf(".");
223
+ const extension = lastDotIndex > 0 ? filename.slice(lastDotIndex) : "";
224
+ const nameWithoutExt = lastDotIndex > 0 ? filename.slice(0, lastDotIndex) : filename;
225
+ const kebabName = kebabCase(nameWithoutExt);
226
+ return kebabName + extension;
227
+ }
220
228
 
221
229
  // src/config/config.ts
222
230
  import { optional, z as z3 } from "zod/mini";
@@ -2374,11 +2382,19 @@ var ClaudecodeIgnore = class _ClaudecodeIgnore extends ToolIgnore {
2374
2382
  const exists = await fileExists(filePath);
2375
2383
  const existingFileContent = exists ? await readFileContent(filePath) : "{}";
2376
2384
  const existingJsonValue = JSON.parse(existingFileContent);
2385
+ const existingDenies = existingJsonValue.permissions?.deny ?? [];
2386
+ const preservedDenies = existingDenies.filter((deny) => {
2387
+ const isReadPattern = deny.startsWith("Read(") && deny.endsWith(")");
2388
+ if (isReadPattern) {
2389
+ return deniedValues.includes(deny);
2390
+ }
2391
+ return true;
2392
+ });
2377
2393
  const jsonValue = {
2378
2394
  ...existingJsonValue,
2379
2395
  permissions: {
2380
2396
  ...existingJsonValue.permissions,
2381
- deny: uniq([...existingJsonValue.permissions?.deny ?? [], ...deniedValues].toSorted())
2397
+ deny: uniq([...preservedDenies, ...deniedValues].toSorted())
2382
2398
  }
2383
2399
  };
2384
2400
  return new _ClaudecodeIgnore({
@@ -3513,6 +3529,12 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
3513
3529
 
3514
3530
  // src/features/mcp/copilot-mcp.ts
3515
3531
  import { join as join33 } from "path";
3532
+ function convertToCopilotFormat(mcpServers) {
3533
+ return { servers: mcpServers };
3534
+ }
3535
+ function convertFromCopilotFormat(copilotConfig) {
3536
+ return copilotConfig.servers ?? {};
3537
+ }
3516
3538
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
3517
3539
  json;
3518
3540
  constructor(params) {
@@ -3552,16 +3574,20 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
3552
3574
  rulesyncMcp,
3553
3575
  validate = true
3554
3576
  }) {
3577
+ const copilotConfig = convertToCopilotFormat(rulesyncMcp.getMcpServers());
3555
3578
  return new _CopilotMcp({
3556
3579
  baseDir,
3557
3580
  relativeDirPath: this.getSettablePaths().relativeDirPath,
3558
3581
  relativeFilePath: this.getSettablePaths().relativeFilePath,
3559
- fileContent: rulesyncMcp.getFileContent(),
3582
+ fileContent: JSON.stringify(copilotConfig, null, 2),
3560
3583
  validate
3561
3584
  });
3562
3585
  }
3563
3586
  toRulesyncMcp() {
3564
- return this.toRulesyncMcpDefault();
3587
+ const mcpServers = convertFromCopilotFormat(this.json);
3588
+ return this.toRulesyncMcpDefault({
3589
+ fileContent: JSON.stringify({ mcpServers }, null, 2)
3590
+ });
3565
3591
  }
3566
3592
  validate() {
3567
3593
  return { success: true, error: null };
@@ -3945,6 +3971,37 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
3945
3971
 
3946
3972
  // src/features/mcp/roo-mcp.ts
3947
3973
  import { join as join38 } from "path";
3974
+ function isRooMcpServers(value) {
3975
+ return value !== void 0 && value !== null && typeof value === "object";
3976
+ }
3977
+ function convertToRooFormat(mcpServers) {
3978
+ return Object.fromEntries(
3979
+ Object.entries(mcpServers).map(([serverName, serverConfig]) => {
3980
+ const converted = { ...serverConfig };
3981
+ if (serverConfig.type === "http") {
3982
+ converted.type = "streamable-http";
3983
+ }
3984
+ if (serverConfig.transport === "http") {
3985
+ converted.transport = "streamable-http";
3986
+ }
3987
+ return [serverName, converted];
3988
+ })
3989
+ );
3990
+ }
3991
+ function convertFromRooFormat(mcpServers) {
3992
+ return Object.fromEntries(
3993
+ Object.entries(mcpServers).map(([serverName, serverConfig]) => {
3994
+ const converted = { ...serverConfig };
3995
+ if (serverConfig.type === "streamable-http") {
3996
+ converted.type = "http";
3997
+ }
3998
+ if (serverConfig.transport === "streamable-http") {
3999
+ converted.transport = "http";
4000
+ }
4001
+ return [serverName, converted];
4002
+ })
4003
+ );
4004
+ }
3948
4005
  var RooMcp = class _RooMcp extends ToolMcp {
3949
4006
  json;
3950
4007
  constructor(params) {
@@ -3984,7 +4041,9 @@ var RooMcp = class _RooMcp extends ToolMcp {
3984
4041
  rulesyncMcp,
3985
4042
  validate = true
3986
4043
  }) {
3987
- const fileContent = rulesyncMcp.getFileContent();
4044
+ const mcpServers = rulesyncMcp.getMcpServers();
4045
+ const convertedMcpServers = convertToRooFormat(mcpServers);
4046
+ const fileContent = JSON.stringify({ mcpServers: convertedMcpServers }, null, 2);
3988
4047
  return new _RooMcp({
3989
4048
  baseDir,
3990
4049
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -3994,7 +4053,11 @@ var RooMcp = class _RooMcp extends ToolMcp {
3994
4053
  });
3995
4054
  }
3996
4055
  toRulesyncMcp() {
3997
- return this.toRulesyncMcpDefault();
4056
+ const rawMcpServers = isRooMcpServers(this.json.mcpServers) ? this.json.mcpServers : {};
4057
+ const convertedMcpServers = convertFromRooFormat(rawMcpServers);
4058
+ return this.toRulesyncMcpDefault({
4059
+ fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
4060
+ });
3998
4061
  }
3999
4062
  validate() {
4000
4063
  return { success: true, error: null };
@@ -4237,19 +4300,21 @@ var McpProcessor = class extends FeatureProcessor {
4237
4300
  // src/features/rules/rules-processor.ts
4238
4301
  import { basename as basename21, join as join82 } from "path";
4239
4302
  import { encode } from "@toon-format/toon";
4240
- import { z as z33 } from "zod/mini";
4241
-
4242
- // src/features/skills/codexcli-skill.ts
4243
- import { join as join42 } from "path";
4244
- import { z as z20 } from "zod/mini";
4303
+ import { z as z34 } from "zod/mini";
4245
4304
 
4246
4305
  // src/constants/general.ts
4247
4306
  var SKILL_FILE_NAME = "SKILL.md";
4248
4307
 
4249
- // src/features/skills/rulesync-skill.ts
4250
- import { join as join40 } from "path";
4308
+ // src/features/skills/agentsmd-skill.ts
4309
+ import { join as join42 } from "path";
4310
+
4311
+ // src/features/skills/simulated-skill.ts
4312
+ import { join as join41 } from "path";
4251
4313
  import { z as z19 } from "zod/mini";
4252
4314
 
4315
+ // src/features/skills/tool-skill.ts
4316
+ import { join as join40 } from "path";
4317
+
4253
4318
  // src/types/ai-dir.ts
4254
4319
  import path2, { basename as basename14, join as join39, relative as relative3, resolve as resolve4 } from "path";
4255
4320
  var AiDir = class {
@@ -4362,113 +4427,7 @@ var AiDir = class {
4362
4427
  }
4363
4428
  };
4364
4429
 
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
4430
  // src/features/skills/tool-skill.ts
4471
- import { join as join41 } from "path";
4472
4431
  var ToolSkill = class extends AiDir {
4473
4432
  /**
4474
4433
  * Get the settable paths for this tool's skill directories.
@@ -4542,8 +4501,8 @@ var ToolSkill = class extends AiDir {
4542
4501
  }) {
4543
4502
  const settablePaths = getSettablePaths({ global });
4544
4503
  const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4545
- const skillDirPath = join41(baseDir, actualRelativeDirPath, dirName);
4546
- const skillFilePath = join41(skillDirPath, SKILL_FILE_NAME);
4504
+ const skillDirPath = join40(baseDir, actualRelativeDirPath, dirName);
4505
+ const skillFilePath = join40(skillDirPath, SKILL_FILE_NAME);
4547
4506
  if (!await fileExists(skillFilePath)) {
4548
4507
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4549
4508
  }
@@ -4567,21 +4526,22 @@ var ToolSkill = class extends AiDir {
4567
4526
  }
4568
4527
  };
4569
4528
 
4570
- // src/features/skills/codexcli-skill.ts
4571
- var CodexCliSkillFrontmatterSchema = z20.object({
4572
- name: z20.string(),
4573
- description: z20.string()
4529
+ // src/features/skills/simulated-skill.ts
4530
+ var SimulatedSkillFrontmatterSchema = z19.object({
4531
+ name: z19.string(),
4532
+ description: z19.string()
4574
4533
  });
4575
- var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4534
+ var SimulatedSkill = class extends ToolSkill {
4535
+ frontmatter;
4536
+ body;
4576
4537
  constructor({
4577
4538
  baseDir = process.cwd(),
4578
- relativeDirPath = join42(".codex", "skills"),
4539
+ relativeDirPath,
4579
4540
  dirName,
4580
4541
  frontmatter,
4581
4542
  body,
4582
4543
  otherFiles = [],
4583
- validate = true,
4584
- global = false
4544
+ validate = true
4585
4545
  }) {
4586
4546
  super({
4587
4547
  baseDir,
@@ -4593,42 +4553,37 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4593
4553
  frontmatter: { ...frontmatter }
4594
4554
  },
4595
4555
  otherFiles,
4596
- global
4556
+ global: false
4557
+ // Simulated skills are project mode only
4597
4558
  });
4598
4559
  if (validate) {
4599
- const result = this.validate();
4560
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4600
4561
  if (!result.success) {
4601
- throw result.error;
4562
+ throw new Error(
4563
+ `Invalid frontmatter in ${join41(relativeDirPath, dirName)}: ${formatError(result.error)}`
4564
+ );
4602
4565
  }
4603
4566
  }
4567
+ this.frontmatter = frontmatter;
4568
+ this.body = body;
4604
4569
  }
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
- };
4570
+ getBody() {
4571
+ return this.body;
4612
4572
  }
4613
4573
  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;
4574
+ return this.frontmatter;
4619
4575
  }
4620
- getBody() {
4621
- return this.mainFile?.body ?? "";
4576
+ toRulesyncSkill() {
4577
+ throw new Error("Not implemented because it is a SIMULATED skill.");
4622
4578
  }
4623
4579
  validate() {
4624
- if (!this.mainFile) {
4625
- return {
4626
- success: false,
4627
- error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
4628
- };
4580
+ if (!this.frontmatter) {
4581
+ return { success: true, error: null };
4629
4582
  }
4630
- const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
4631
- if (!result.success) {
4583
+ const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
4584
+ if (result.success) {
4585
+ return { success: true, error: null };
4586
+ } else {
4632
4587
  return {
4633
4588
  success: false,
4634
4589
  error: new Error(
@@ -4636,98 +4591,141 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4636
4591
  )
4637
4592
  };
4638
4593
  }
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
4594
  }
4659
- static fromRulesyncSkill({
4595
+ static fromRulesyncSkillDefault({
4660
4596
  rulesyncSkill,
4661
- validate = true,
4662
- global = false
4597
+ validate = true
4663
4598
  }) {
4664
- const settablePaths = _CodexCliSkill.getSettablePaths({ global });
4665
4599
  const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4666
- const codexFrontmatter = {
4600
+ const simulatedFrontmatter = {
4667
4601
  name: rulesyncFrontmatter.name,
4668
4602
  description: rulesyncFrontmatter.description
4669
4603
  };
4670
- return new _CodexCliSkill({
4604
+ return {
4671
4605
  baseDir: rulesyncSkill.getBaseDir(),
4672
- relativeDirPath: settablePaths.relativeDirPath,
4606
+ relativeDirPath: this.getSettablePaths().relativeDirPath,
4673
4607
  dirName: rulesyncSkill.getDirName(),
4674
- frontmatter: codexFrontmatter,
4608
+ frontmatter: simulatedFrontmatter,
4675
4609
  body: rulesyncSkill.getBody(),
4676
4610
  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");
4611
+ validate
4612
+ };
4684
4613
  }
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
- );
4696
- }
4697
- return new _CodexCliSkill({
4698
- baseDir: loaded.baseDir,
4699
- relativeDirPath: loaded.relativeDirPath,
4700
- dirName: loaded.dirName,
4614
+ static async fromDirDefault({
4615
+ baseDir = process.cwd(),
4616
+ relativeDirPath,
4617
+ dirName
4618
+ }) {
4619
+ const settablePaths = this.getSettablePaths();
4620
+ const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4621
+ const skillDirPath = join41(baseDir, actualRelativeDirPath, dirName);
4622
+ const skillFilePath = join41(skillDirPath, SKILL_FILE_NAME);
4623
+ if (!await fileExists(skillFilePath)) {
4624
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4625
+ }
4626
+ const fileContent = await readFileContent(skillFilePath);
4627
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
4628
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4629
+ if (!result.success) {
4630
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4631
+ }
4632
+ const otherFiles = await this.collectOtherFiles(
4633
+ baseDir,
4634
+ actualRelativeDirPath,
4635
+ dirName,
4636
+ SKILL_FILE_NAME
4637
+ );
4638
+ return {
4639
+ baseDir,
4640
+ relativeDirPath: actualRelativeDirPath,
4641
+ dirName,
4701
4642
  frontmatter: result.data,
4702
- body: loaded.body,
4703
- otherFiles: loaded.otherFiles,
4704
- validate: true,
4705
- global: loaded.global
4643
+ body: content.trim(),
4644
+ otherFiles,
4645
+ validate: true
4646
+ };
4647
+ }
4648
+ /**
4649
+ * Check if a RulesyncSkill should be converted to this simulated skill type.
4650
+ * Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
4651
+ */
4652
+ static isTargetedByRulesyncSkillDefault({
4653
+ rulesyncSkill,
4654
+ toolTarget
4655
+ }) {
4656
+ const frontmatter = rulesyncSkill.getFrontmatter();
4657
+ const targets = frontmatter.targets;
4658
+ if (targets.includes("*")) {
4659
+ return true;
4660
+ }
4661
+ return targets.includes(toolTarget);
4662
+ }
4663
+ /**
4664
+ * Get the settable paths for this tool's skill directories.
4665
+ * Must be implemented by concrete subclasses.
4666
+ */
4667
+ static getSettablePaths(_options) {
4668
+ throw new Error("Please implement this method in the subclass.");
4669
+ }
4670
+ };
4671
+
4672
+ // src/features/skills/agentsmd-skill.ts
4673
+ var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
4674
+ static getSettablePaths(options) {
4675
+ if (options?.global) {
4676
+ throw new Error("AgentsmdSkill does not support global mode.");
4677
+ }
4678
+ return {
4679
+ relativeDirPath: join42(".agents", "skills")
4680
+ };
4681
+ }
4682
+ static async fromDir(params) {
4683
+ const baseParams = await this.fromDirDefault(params);
4684
+ return new _AgentsmdSkill(baseParams);
4685
+ }
4686
+ static fromRulesyncSkill(params) {
4687
+ const baseParams = {
4688
+ ...this.fromRulesyncSkillDefault(params),
4689
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4690
+ };
4691
+ return new _AgentsmdSkill(baseParams);
4692
+ }
4693
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4694
+ return this.isTargetedByRulesyncSkillDefault({
4695
+ rulesyncSkill,
4696
+ toolTarget: "agentsmd"
4706
4697
  });
4707
4698
  }
4708
4699
  };
4709
4700
 
4710
- // src/features/skills/copilot-skill.ts
4701
+ // src/features/skills/codexcli-skill.ts
4711
4702
  import { join as join44 } from "path";
4703
+ import { z as z21 } from "zod/mini";
4712
4704
 
4713
- // src/features/skills/simulated-skill.ts
4705
+ // src/features/skills/rulesync-skill.ts
4714
4706
  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()
4707
+ import { z as z20 } from "zod/mini";
4708
+ var RulesyncSkillFrontmatterSchemaInternal = z20.object({
4709
+ name: z20.string(),
4710
+ description: z20.string(),
4711
+ targets: z20._default(RulesyncTargetsSchema, ["*"]),
4712
+ claudecode: z20.optional(
4713
+ z20.object({
4714
+ "allowed-tools": z20.optional(z20.array(z20.string()))
4715
+ })
4716
+ )
4719
4717
  });
4720
- var SimulatedSkill = class extends ToolSkill {
4721
- frontmatter;
4722
- body;
4718
+ var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
4719
+ var RulesyncSkill = class _RulesyncSkill extends AiDir {
4723
4720
  constructor({
4724
4721
  baseDir = process.cwd(),
4725
- relativeDirPath,
4722
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4726
4723
  dirName,
4727
4724
  frontmatter,
4728
4725
  body,
4729
4726
  otherFiles = [],
4730
- validate = true
4727
+ validate = true,
4728
+ global = false
4731
4729
  }) {
4732
4730
  super({
4733
4731
  baseDir,
@@ -4739,37 +4737,33 @@ var SimulatedSkill = class extends ToolSkill {
4739
4737
  frontmatter: { ...frontmatter }
4740
4738
  },
4741
4739
  otherFiles,
4742
- global: false
4743
- // Simulated skills are project mode only
4740
+ global
4744
4741
  });
4745
4742
  if (validate) {
4746
- const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4743
+ const result = this.validate();
4747
4744
  if (!result.success) {
4748
- throw new Error(
4749
- `Invalid frontmatter in ${join43(relativeDirPath, dirName)}: ${formatError(result.error)}`
4750
- );
4745
+ throw result.error;
4751
4746
  }
4752
4747
  }
4753
- this.frontmatter = frontmatter;
4754
- this.body = body;
4755
4748
  }
4756
- getBody() {
4757
- return this.body;
4749
+ static getSettablePaths() {
4750
+ return {
4751
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
4752
+ };
4758
4753
  }
4759
4754
  getFrontmatter() {
4760
- return this.frontmatter;
4755
+ if (!this.mainFile?.frontmatter) {
4756
+ throw new Error("Frontmatter is not defined");
4757
+ }
4758
+ const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4759
+ return result;
4761
4760
  }
4762
- toRulesyncSkill() {
4763
- throw new Error("Not implemented because it is a SIMULATED skill.");
4761
+ getBody() {
4762
+ return this.mainFile?.body ?? "";
4764
4763
  }
4765
4764
  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 {
4765
+ const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
4766
+ if (!result.success) {
4773
4767
  return {
4774
4768
  success: false,
4775
4769
  error: new Error(
@@ -4777,92 +4771,193 @@ var SimulatedSkill = class extends ToolSkill {
4777
4771
  )
4778
4772
  };
4779
4773
  }
4774
+ return { success: true, error: null };
4780
4775
  }
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({
4776
+ static async fromDir({
4801
4777
  baseDir = process.cwd(),
4802
- relativeDirPath,
4803
- dirName
4778
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4779
+ dirName,
4780
+ global = false
4804
4781
  }) {
4805
- const settablePaths = this.getSettablePaths();
4806
- const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4807
- const skillDirPath = join43(baseDir, actualRelativeDirPath, dirName);
4782
+ const skillDirPath = join43(baseDir, relativeDirPath, dirName);
4808
4783
  const skillFilePath = join43(skillDirPath, SKILL_FILE_NAME);
4809
4784
  if (!await fileExists(skillFilePath)) {
4810
4785
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4811
4786
  }
4812
4787
  const fileContent = await readFileContent(skillFilePath);
4813
4788
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4814
- const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4789
+ const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
4815
4790
  if (!result.success) {
4816
4791
  throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4817
4792
  }
4818
4793
  const otherFiles = await this.collectOtherFiles(
4819
4794
  baseDir,
4820
- actualRelativeDirPath,
4795
+ relativeDirPath,
4821
4796
  dirName,
4822
4797
  SKILL_FILE_NAME
4823
4798
  );
4824
- return {
4799
+ return new _RulesyncSkill({
4825
4800
  baseDir,
4826
- relativeDirPath: actualRelativeDirPath,
4801
+ relativeDirPath,
4827
4802
  dirName,
4828
4803
  frontmatter: result.data,
4829
4804
  body: content.trim(),
4830
4805
  otherFiles,
4831
- validate: true
4806
+ validate: true,
4807
+ global
4808
+ });
4809
+ }
4810
+ };
4811
+
4812
+ // src/features/skills/codexcli-skill.ts
4813
+ var CodexCliSkillFrontmatterSchema = z21.object({
4814
+ name: z21.string(),
4815
+ description: z21.string()
4816
+ });
4817
+ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
4818
+ constructor({
4819
+ baseDir = process.cwd(),
4820
+ relativeDirPath = join44(".codex", "skills"),
4821
+ dirName,
4822
+ frontmatter,
4823
+ body,
4824
+ otherFiles = [],
4825
+ validate = true,
4826
+ global = false
4827
+ }) {
4828
+ super({
4829
+ baseDir,
4830
+ relativeDirPath,
4831
+ dirName,
4832
+ mainFile: {
4833
+ name: SKILL_FILE_NAME,
4834
+ body,
4835
+ frontmatter: { ...frontmatter }
4836
+ },
4837
+ otherFiles,
4838
+ global
4839
+ });
4840
+ if (validate) {
4841
+ const result = this.validate();
4842
+ if (!result.success) {
4843
+ throw result.error;
4844
+ }
4845
+ }
4846
+ }
4847
+ static getSettablePaths({ global = false } = {}) {
4848
+ if (!global) {
4849
+ throw new Error("CodexCliSkill only supports global mode. Please pass { global: true }.");
4850
+ }
4851
+ return {
4852
+ relativeDirPath: join44(".codex", "skills")
4832
4853
  };
4833
4854
  }
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({
4855
+ getFrontmatter() {
4856
+ if (!this.mainFile?.frontmatter) {
4857
+ throw new Error("Frontmatter is not defined");
4858
+ }
4859
+ const result = CodexCliSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4860
+ return result;
4861
+ }
4862
+ getBody() {
4863
+ return this.mainFile?.body ?? "";
4864
+ }
4865
+ validate() {
4866
+ if (!this.mainFile) {
4867
+ return {
4868
+ success: false,
4869
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
4870
+ };
4871
+ }
4872
+ const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
4873
+ if (!result.success) {
4874
+ return {
4875
+ success: false,
4876
+ error: new Error(
4877
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4878
+ )
4879
+ };
4880
+ }
4881
+ return { success: true, error: null };
4882
+ }
4883
+ toRulesyncSkill() {
4884
+ const frontmatter = this.getFrontmatter();
4885
+ const rulesyncFrontmatter = {
4886
+ name: frontmatter.name,
4887
+ description: frontmatter.description,
4888
+ targets: ["*"]
4889
+ };
4890
+ return new RulesyncSkill({
4891
+ baseDir: this.baseDir,
4892
+ relativeDirPath: this.relativeDirPath,
4893
+ dirName: this.getDirName(),
4894
+ frontmatter: rulesyncFrontmatter,
4895
+ body: this.getBody(),
4896
+ otherFiles: this.getOtherFiles(),
4897
+ validate: true,
4898
+ global: this.global
4899
+ });
4900
+ }
4901
+ static fromRulesyncSkill({
4839
4902
  rulesyncSkill,
4840
- toolTarget
4903
+ validate = true,
4904
+ global = false
4841
4905
  }) {
4842
- const frontmatter = rulesyncSkill.getFrontmatter();
4843
- const targets = frontmatter.targets;
4844
- if (targets.includes("*")) {
4845
- return true;
4846
- }
4847
- return targets.includes(toolTarget);
4906
+ const settablePaths = _CodexCliSkill.getSettablePaths({ global });
4907
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4908
+ const codexFrontmatter = {
4909
+ name: rulesyncFrontmatter.name,
4910
+ description: rulesyncFrontmatter.description
4911
+ };
4912
+ return new _CodexCliSkill({
4913
+ baseDir: rulesyncSkill.getBaseDir(),
4914
+ relativeDirPath: settablePaths.relativeDirPath,
4915
+ dirName: rulesyncSkill.getDirName(),
4916
+ frontmatter: codexFrontmatter,
4917
+ body: rulesyncSkill.getBody(),
4918
+ otherFiles: rulesyncSkill.getOtherFiles(),
4919
+ validate,
4920
+ global
4921
+ });
4848
4922
  }
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.");
4923
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4924
+ const targets = rulesyncSkill.getFrontmatter().targets;
4925
+ return targets.includes("*") || targets.includes("codexcli");
4926
+ }
4927
+ static async fromDir(params) {
4928
+ const loaded = await this.loadSkillDirContent({
4929
+ ...params,
4930
+ getSettablePaths: _CodexCliSkill.getSettablePaths
4931
+ });
4932
+ const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
4933
+ if (!result.success) {
4934
+ const skillDirPath = join44(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
4935
+ throw new Error(
4936
+ `Invalid frontmatter in ${join44(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
4937
+ );
4938
+ }
4939
+ return new _CodexCliSkill({
4940
+ baseDir: loaded.baseDir,
4941
+ relativeDirPath: loaded.relativeDirPath,
4942
+ dirName: loaded.dirName,
4943
+ frontmatter: result.data,
4944
+ body: loaded.body,
4945
+ otherFiles: loaded.otherFiles,
4946
+ validate: true,
4947
+ global: loaded.global
4948
+ });
4855
4949
  }
4856
4950
  };
4857
4951
 
4858
4952
  // src/features/skills/copilot-skill.ts
4953
+ import { join as join45 } from "path";
4859
4954
  var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
4860
4955
  static getSettablePaths(options) {
4861
4956
  if (options?.global) {
4862
4957
  throw new Error("CopilotSkill does not support global mode.");
4863
4958
  }
4864
4959
  return {
4865
- relativeDirPath: join44(".github", "skills")
4960
+ relativeDirPath: join45(".github", "skills")
4866
4961
  };
4867
4962
  }
4868
4963
  static async fromDir(params) {
@@ -4885,14 +4980,14 @@ var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
4885
4980
  };
4886
4981
 
4887
4982
  // src/features/skills/cursor-skill.ts
4888
- import { join as join45 } from "path";
4983
+ import { join as join46 } from "path";
4889
4984
  var CursorSkill = class _CursorSkill extends SimulatedSkill {
4890
4985
  static getSettablePaths(options) {
4891
4986
  if (options?.global) {
4892
4987
  throw new Error("CursorSkill does not support global mode.");
4893
4988
  }
4894
4989
  return {
4895
- relativeDirPath: join45(".cursor", "skills")
4990
+ relativeDirPath: join46(".cursor", "skills")
4896
4991
  };
4897
4992
  }
4898
4993
  static async fromDir(params) {
@@ -4914,12 +5009,42 @@ var CursorSkill = class _CursorSkill extends SimulatedSkill {
4914
5009
  }
4915
5010
  };
4916
5011
 
5012
+ // src/features/skills/geminicli-skill.ts
5013
+ import { join as join47 } from "path";
5014
+ var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
5015
+ static getSettablePaths(options) {
5016
+ if (options?.global) {
5017
+ throw new Error("GeminiCliSkill does not support global mode.");
5018
+ }
5019
+ return {
5020
+ relativeDirPath: join47(".gemini", "skills")
5021
+ };
5022
+ }
5023
+ static async fromDir(params) {
5024
+ const baseParams = await this.fromDirDefault(params);
5025
+ return new _GeminiCliSkill(baseParams);
5026
+ }
5027
+ static fromRulesyncSkill(params) {
5028
+ const baseParams = {
5029
+ ...this.fromRulesyncSkillDefault(params),
5030
+ relativeDirPath: this.getSettablePaths().relativeDirPath
5031
+ };
5032
+ return new _GeminiCliSkill(baseParams);
5033
+ }
5034
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
5035
+ return this.isTargetedByRulesyncSkillDefault({
5036
+ rulesyncSkill,
5037
+ toolTarget: "geminicli"
5038
+ });
5039
+ }
5040
+ };
5041
+
4917
5042
  // src/features/skills/skills-processor.ts
4918
5043
  import { basename as basename15, join as join50 } from "path";
4919
5044
  import { z as z23 } from "zod/mini";
4920
5045
 
4921
5046
  // src/types/dir-feature-processor.ts
4922
- import { join as join46 } from "path";
5047
+ import { join as join48 } from "path";
4923
5048
  var DirFeatureProcessor = class {
4924
5049
  baseDir;
4925
5050
  constructor({ baseDir = process.cwd() }) {
@@ -4941,14 +5066,14 @@ var DirFeatureProcessor = class {
4941
5066
  await ensureDir(dirPath);
4942
5067
  const mainFile = aiDir.getMainFile();
4943
5068
  if (mainFile) {
4944
- const mainFilePath = join46(dirPath, mainFile.name);
5069
+ const mainFilePath = join48(dirPath, mainFile.name);
4945
5070
  const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter);
4946
5071
  const contentWithNewline = addTrailingNewline(content);
4947
5072
  await writeFileContent(mainFilePath, contentWithNewline);
4948
5073
  }
4949
5074
  const otherFiles = aiDir.getOtherFiles();
4950
5075
  for (const file of otherFiles) {
4951
- const filePath = join46(dirPath, file.relativeFilePathToDirPath);
5076
+ const filePath = join48(dirPath, file.relativeFilePathToDirPath);
4952
5077
  const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
4953
5078
  await writeFileContent(filePath, contentWithNewline);
4954
5079
  }
@@ -4962,38 +5087,8 @@ var DirFeatureProcessor = class {
4962
5087
  }
4963
5088
  };
4964
5089
 
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
5090
  // src/features/skills/claudecode-skill.ts
4996
- import { join as join48 } from "path";
5091
+ import { join as join49 } from "path";
4997
5092
  import { z as z22 } from "zod/mini";
4998
5093
  var ClaudecodeSkillFrontmatterSchema = z22.object({
4999
5094
  name: z22.string(),
@@ -5003,7 +5098,7 @@ var ClaudecodeSkillFrontmatterSchema = z22.object({
5003
5098
  var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5004
5099
  constructor({
5005
5100
  baseDir = process.cwd(),
5006
- relativeDirPath = join48(".claude", "skills"),
5101
+ relativeDirPath = join49(".claude", "skills"),
5007
5102
  dirName,
5008
5103
  frontmatter,
5009
5104
  body,
@@ -5034,7 +5129,7 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5034
5129
  global: _global = false
5035
5130
  } = {}) {
5036
5131
  return {
5037
- relativeDirPath: join48(".claude", "skills")
5132
+ relativeDirPath: join49(".claude", "skills")
5038
5133
  };
5039
5134
  }
5040
5135
  getFrontmatter() {
@@ -5121,9 +5216,9 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5121
5216
  });
5122
5217
  const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
5123
5218
  if (!result.success) {
5124
- const skillDirPath = join48(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
5219
+ const skillDirPath = join49(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
5125
5220
  throw new Error(
5126
- `Invalid frontmatter in ${join48(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
5221
+ `Invalid frontmatter in ${join49(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
5127
5222
  );
5128
5223
  }
5129
5224
  return new _ClaudecodeSkill({
@@ -5139,36 +5234,6 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
5139
5234
  }
5140
5235
  };
5141
5236
 
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
5237
  // src/features/skills/skills-processor.ts
5173
5238
  var skillsProcessorToolTargetTuple = [
5174
5239
  "agentsmd",
@@ -6101,6 +6166,12 @@ var RulesyncRuleFrontmatterSchema = z28.object({
6101
6166
  z28.object({
6102
6167
  excludeAgent: z28.optional(z28.union([z28.literal("code-review"), z28.literal("coding-agent")]))
6103
6168
  })
6169
+ ),
6170
+ antigravity: z28.optional(
6171
+ z28.looseObject({
6172
+ trigger: z28.optional(z28.string()),
6173
+ globs: z28.optional(z28.array(z28.string()))
6174
+ })
6104
6175
  )
6105
6176
  });
6106
6177
  var RulesyncRule = class _RulesyncRule extends RulesyncFile {
@@ -6470,7 +6541,176 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
6470
6541
 
6471
6542
  // src/features/rules/antigravity-rule.ts
6472
6543
  import { join as join65 } from "path";
6544
+ import { z as z29 } from "zod/mini";
6545
+ var AntigravityRuleFrontmatterSchema = z29.looseObject({
6546
+ trigger: z29.optional(
6547
+ z29.union([
6548
+ z29.literal("always_on"),
6549
+ z29.literal("glob"),
6550
+ z29.literal("manual"),
6551
+ z29.literal("model_decision"),
6552
+ z29.string()
6553
+ // accepts any string for forward compatibility
6554
+ ])
6555
+ ),
6556
+ globs: z29.optional(z29.string()),
6557
+ description: z29.optional(z29.string())
6558
+ });
6559
+ function parseGlobsString(globs) {
6560
+ if (!globs) {
6561
+ return [];
6562
+ }
6563
+ if (Array.isArray(globs)) {
6564
+ return globs;
6565
+ }
6566
+ if (globs.trim() === "") {
6567
+ return [];
6568
+ }
6569
+ return globs.split(",").map((g) => g.trim());
6570
+ }
6571
+ function stringifyGlobs(globs) {
6572
+ if (!globs || globs.length === 0) {
6573
+ return void 0;
6574
+ }
6575
+ return globs.join(",");
6576
+ }
6577
+ function normalizeStoredAntigravity(stored) {
6578
+ if (!stored) {
6579
+ return void 0;
6580
+ }
6581
+ const { globs, ...rest } = stored;
6582
+ return {
6583
+ ...rest,
6584
+ globs: Array.isArray(globs) ? stringifyGlobs(globs) : globs
6585
+ };
6586
+ }
6587
+ var globStrategy = {
6588
+ canHandle: (trigger) => trigger === "glob",
6589
+ generateFrontmatter: (normalized, rulesyncFrontmatter) => {
6590
+ const effectiveGlobsArray = normalized?.globs ? parseGlobsString(normalized.globs) : rulesyncFrontmatter.globs ?? [];
6591
+ return {
6592
+ ...normalized,
6593
+ trigger: "glob",
6594
+ globs: stringifyGlobs(effectiveGlobsArray)
6595
+ };
6596
+ },
6597
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6598
+ globs: parseGlobsString(frontmatter.globs),
6599
+ description: description || "",
6600
+ antigravity: frontmatter
6601
+ })
6602
+ };
6603
+ var manualStrategy = {
6604
+ canHandle: (trigger) => trigger === "manual",
6605
+ generateFrontmatter: (normalized) => ({
6606
+ ...normalized,
6607
+ trigger: "manual"
6608
+ }),
6609
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6610
+ globs: [],
6611
+ description: description || "",
6612
+ antigravity: frontmatter
6613
+ })
6614
+ };
6615
+ var alwaysOnStrategy = {
6616
+ canHandle: (trigger) => trigger === "always_on",
6617
+ generateFrontmatter: (normalized) => ({
6618
+ ...normalized,
6619
+ trigger: "always_on"
6620
+ }),
6621
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6622
+ globs: ["**/*"],
6623
+ description: description || "",
6624
+ antigravity: frontmatter
6625
+ })
6626
+ };
6627
+ var modelDecisionStrategy = {
6628
+ canHandle: (trigger) => trigger === "model_decision",
6629
+ generateFrontmatter: (normalized, rulesyncFrontmatter) => ({
6630
+ ...normalized,
6631
+ trigger: "model_decision",
6632
+ description: rulesyncFrontmatter.description
6633
+ }),
6634
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6635
+ globs: [],
6636
+ description: description || "",
6637
+ antigravity: frontmatter
6638
+ })
6639
+ };
6640
+ var unknownStrategy = {
6641
+ canHandle: (trigger) => trigger !== void 0,
6642
+ generateFrontmatter: (normalized) => {
6643
+ const trigger = typeof normalized?.trigger === "string" ? normalized.trigger : "manual";
6644
+ return {
6645
+ ...normalized,
6646
+ trigger
6647
+ };
6648
+ },
6649
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6650
+ globs: frontmatter.globs ? parseGlobsString(frontmatter.globs) : ["**/*"],
6651
+ description: description || "",
6652
+ antigravity: frontmatter
6653
+ })
6654
+ };
6655
+ var inferenceStrategy = {
6656
+ canHandle: (trigger) => trigger === void 0,
6657
+ generateFrontmatter: (normalized, rulesyncFrontmatter) => {
6658
+ const effectiveGlobsArray = normalized?.globs ? parseGlobsString(normalized.globs) : rulesyncFrontmatter.globs ?? [];
6659
+ if (effectiveGlobsArray.length > 0 && !effectiveGlobsArray.includes("**/*") && !effectiveGlobsArray.includes("*")) {
6660
+ return {
6661
+ ...normalized,
6662
+ trigger: "glob",
6663
+ globs: stringifyGlobs(effectiveGlobsArray)
6664
+ };
6665
+ }
6666
+ return {
6667
+ ...normalized,
6668
+ trigger: "always_on"
6669
+ };
6670
+ },
6671
+ exportRulesyncData: ({ description, ...frontmatter }) => ({
6672
+ globs: frontmatter.globs ? parseGlobsString(frontmatter.globs) : ["**/*"],
6673
+ description: description || "",
6674
+ antigravity: frontmatter
6675
+ })
6676
+ };
6677
+ var STRATEGIES = [
6678
+ globStrategy,
6679
+ manualStrategy,
6680
+ alwaysOnStrategy,
6681
+ modelDecisionStrategy,
6682
+ unknownStrategy,
6683
+ inferenceStrategy
6684
+ ];
6473
6685
  var AntigravityRule = class _AntigravityRule extends ToolRule {
6686
+ frontmatter;
6687
+ body;
6688
+ /**
6689
+ * Creates an AntigravityRule instance.
6690
+ *
6691
+ * @param params - Rule parameters including frontmatter and body
6692
+ * @param params.frontmatter - Antigravity-specific frontmatter configuration
6693
+ * @param params.body - The markdown body content (without frontmatter)
6694
+ *
6695
+ * Note: Files without frontmatter will default to always_on trigger during fromFile().
6696
+ */
6697
+ constructor({ frontmatter, body, ...rest }) {
6698
+ if (rest.validate !== false) {
6699
+ const result = AntigravityRuleFrontmatterSchema.safeParse(frontmatter);
6700
+ if (!result.success) {
6701
+ throw new Error(
6702
+ `Invalid frontmatter in ${join65(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
6703
+ );
6704
+ }
6705
+ }
6706
+ super({
6707
+ ...rest,
6708
+ // Ensure fileContent includes frontmatter when constructed directly
6709
+ fileContent: stringifyFrontmatter(body, frontmatter)
6710
+ });
6711
+ this.frontmatter = frontmatter;
6712
+ this.body = body;
6713
+ }
6474
6714
  static getSettablePaths() {
6475
6715
  return {
6476
6716
  nonRoot: {
@@ -6483,36 +6723,121 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
6483
6723
  relativeFilePath,
6484
6724
  validate = true
6485
6725
  }) {
6486
- const fileContent = await readFileContent(
6487
- join65(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6726
+ const filePath = join65(
6727
+ baseDir,
6728
+ this.getSettablePaths().nonRoot.relativeDirPath,
6729
+ relativeFilePath
6488
6730
  );
6731
+ const fileContent = await readFileContent(filePath);
6732
+ const { frontmatter, body } = parseFrontmatter(fileContent);
6733
+ let parsedFrontmatter;
6734
+ if (validate) {
6735
+ const result = AntigravityRuleFrontmatterSchema.safeParse(frontmatter);
6736
+ if (result.success) {
6737
+ parsedFrontmatter = result.data;
6738
+ } else {
6739
+ throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
6740
+ }
6741
+ } else {
6742
+ parsedFrontmatter = frontmatter;
6743
+ }
6489
6744
  return new _AntigravityRule({
6490
6745
  baseDir,
6491
6746
  relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
6492
6747
  relativeFilePath,
6493
- fileContent,
6748
+ body,
6749
+ frontmatter: parsedFrontmatter,
6494
6750
  validate,
6495
6751
  root: false
6496
6752
  });
6497
6753
  }
6754
+ /**
6755
+ * Converts a RulesyncRule to an AntigravityRule.
6756
+ *
6757
+ * Trigger inference:
6758
+ * - If antigravity.trigger is set, it's preserved
6759
+ * - If specific globs are set, infers "glob" trigger
6760
+ * - Otherwise, infers "always_on" trigger
6761
+ */
6498
6762
  static fromRulesyncRule({
6499
6763
  baseDir = process.cwd(),
6500
6764
  rulesyncRule,
6501
6765
  validate = true
6502
6766
  }) {
6503
- return new _AntigravityRule(
6504
- this.buildToolRuleParamsDefault({
6505
- baseDir,
6506
- rulesyncRule,
6507
- validate,
6508
- nonRootPath: this.getSettablePaths().nonRoot
6509
- })
6510
- );
6767
+ const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
6768
+ const storedAntigravity = rulesyncFrontmatter.antigravity;
6769
+ const normalized = normalizeStoredAntigravity(storedAntigravity);
6770
+ const storedTrigger = storedAntigravity?.trigger;
6771
+ const strategy = STRATEGIES.find((s) => s.canHandle(storedTrigger));
6772
+ if (!strategy) {
6773
+ throw new Error(`No strategy found for trigger: ${storedTrigger}`);
6774
+ }
6775
+ const frontmatter = strategy.generateFrontmatter(normalized, rulesyncFrontmatter);
6776
+ const paths = this.getSettablePaths();
6777
+ const kebabCaseFilename = toKebabCaseFilename(rulesyncRule.getRelativeFilePath());
6778
+ return new _AntigravityRule({
6779
+ baseDir,
6780
+ relativeDirPath: paths.nonRoot.relativeDirPath,
6781
+ relativeFilePath: kebabCaseFilename,
6782
+ frontmatter,
6783
+ body: rulesyncRule.getBody(),
6784
+ validate,
6785
+ root: false
6786
+ });
6511
6787
  }
6788
+ /**
6789
+ * Converts this AntigravityRule to a RulesyncRule.
6790
+ *
6791
+ * The Antigravity configuration is preserved in the RulesyncRule's
6792
+ * frontmatter.antigravity field for round-trip compatibility.
6793
+ *
6794
+ * Note: All Antigravity rules are treated as non-root (root: false),
6795
+ * as they are all placed in the .agent/rules directory.
6796
+ *
6797
+ * @returns RulesyncRule instance with Antigravity config preserved
6798
+ */
6512
6799
  toRulesyncRule() {
6513
- return this.toRulesyncRuleDefault();
6800
+ const strategy = STRATEGIES.find((s) => s.canHandle(this.frontmatter.trigger));
6801
+ let rulesyncData = {
6802
+ globs: [],
6803
+ description: "",
6804
+ antigravity: this.frontmatter
6805
+ };
6806
+ if (strategy) {
6807
+ rulesyncData = strategy.exportRulesyncData(this.frontmatter);
6808
+ }
6809
+ const antigravityForRulesync = {
6810
+ ...rulesyncData.antigravity,
6811
+ globs: this.frontmatter.globs ? parseGlobsString(this.frontmatter.globs) : void 0
6812
+ };
6813
+ return new RulesyncRule({
6814
+ baseDir: process.cwd(),
6815
+ relativeDirPath: RulesyncRule.getSettablePaths().recommended.relativeDirPath,
6816
+ relativeFilePath: this.getRelativeFilePath(),
6817
+ frontmatter: {
6818
+ root: false,
6819
+ targets: ["*"],
6820
+ ...rulesyncData,
6821
+ antigravity: antigravityForRulesync
6822
+ },
6823
+ // When converting back, we only want the body content
6824
+ body: this.body
6825
+ });
6826
+ }
6827
+ getBody() {
6828
+ return this.body;
6829
+ }
6830
+ // Helper to access raw file content including frontmatter is `this.fileContent` (from ToolFile)
6831
+ // But we might want `body` only for some operations?
6832
+ // ToolFile.getFileContent() returns the whole string.
6833
+ getFrontmatter() {
6834
+ return this.frontmatter;
6514
6835
  }
6515
6836
  validate() {
6837
+ const result = AntigravityRuleFrontmatterSchema.safeParse(this.frontmatter);
6838
+ if (!result.success) {
6839
+ return { success: false, error: new Error(formatError(result.error)) };
6840
+ }
6516
6841
  return { success: true, error: null };
6517
6842
  }
6518
6843
  static isTargetedByRulesyncRule(rulesyncRule) {
@@ -6746,9 +7071,9 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
6746
7071
 
6747
7072
  // src/features/rules/claudecode-rule.ts
6748
7073
  import { join as join69 } from "path";
6749
- import { z as z29 } from "zod/mini";
6750
- var ClaudecodeRuleFrontmatterSchema = z29.object({
6751
- paths: z29.optional(z29.string())
7074
+ import { z as z30 } from "zod/mini";
7075
+ var ClaudecodeRuleFrontmatterSchema = z30.object({
7076
+ paths: z30.optional(z30.string())
6752
7077
  });
6753
7078
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
6754
7079
  frontmatter;
@@ -6938,9 +7263,9 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
6938
7263
 
6939
7264
  // src/features/rules/cline-rule.ts
6940
7265
  import { join as join70 } from "path";
6941
- import { z as z30 } from "zod/mini";
6942
- var ClineRuleFrontmatterSchema = z30.object({
6943
- description: z30.string()
7266
+ import { z as z31 } from "zod/mini";
7267
+ var ClineRuleFrontmatterSchema = z31.object({
7268
+ description: z31.string()
6944
7269
  });
6945
7270
  var ClineRule = class _ClineRule extends ToolRule {
6946
7271
  static getSettablePaths() {
@@ -7087,11 +7412,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
7087
7412
 
7088
7413
  // src/features/rules/copilot-rule.ts
7089
7414
  import { join as join72 } from "path";
7090
- import { z as z31 } from "zod/mini";
7091
- var CopilotRuleFrontmatterSchema = z31.object({
7092
- description: z31.optional(z31.string()),
7093
- applyTo: z31.optional(z31.string()),
7094
- excludeAgent: z31.optional(z31.union([z31.literal("code-review"), z31.literal("coding-agent")]))
7415
+ import { z as z32 } from "zod/mini";
7416
+ var CopilotRuleFrontmatterSchema = z32.object({
7417
+ description: z32.optional(z32.string()),
7418
+ applyTo: z32.optional(z32.string()),
7419
+ excludeAgent: z32.optional(z32.union([z32.literal("code-review"), z32.literal("coding-agent")]))
7095
7420
  });
7096
7421
  var CopilotRule = class _CopilotRule extends ToolRule {
7097
7422
  frontmatter;
@@ -7259,11 +7584,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
7259
7584
 
7260
7585
  // src/features/rules/cursor-rule.ts
7261
7586
  import { basename as basename20, join as join73 } from "path";
7262
- import { z as z32 } from "zod/mini";
7263
- var CursorRuleFrontmatterSchema = z32.object({
7264
- description: z32.optional(z32.string()),
7265
- globs: z32.optional(z32.string()),
7266
- alwaysApply: z32.optional(z32.boolean())
7587
+ import { z as z33 } from "zod/mini";
7588
+ var CursorRuleFrontmatterSchema = z33.object({
7589
+ description: z33.optional(z33.string()),
7590
+ globs: z33.optional(z33.string()),
7591
+ alwaysApply: z33.optional(z33.boolean())
7267
7592
  });
7268
7593
  var CursorRule = class _CursorRule extends ToolRule {
7269
7594
  frontmatter;
@@ -7981,34 +8306,197 @@ var rulesProcessorToolTargets = [
7981
8306
  "warp",
7982
8307
  "windsurf"
7983
8308
  ];
7984
- var RulesProcessorToolTargetSchema = z33.enum(rulesProcessorToolTargets);
7985
- var rulesProcessorToolTargetsGlobal = [
7986
- "claudecode",
7987
- "claudecode-legacy",
7988
- "codexcli",
7989
- "geminicli"
7990
- ];
8309
+ var RulesProcessorToolTargetSchema = z34.enum(rulesProcessorToolTargets);
7991
8310
  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" } }]
8311
+ [
8312
+ "agentsmd",
8313
+ {
8314
+ class: AgentsMdRule,
8315
+ meta: {
8316
+ extension: "md",
8317
+ supportsGlobal: false,
8318
+ ruleDiscoveryMode: "toon",
8319
+ additionalConventions: {
8320
+ commands: { commandClass: AgentsmdCommand },
8321
+ subagents: { subagentClass: AgentsmdSubagent },
8322
+ skills: { skillClass: AgentsmdSkill }
8323
+ }
8324
+ }
8325
+ }
8326
+ ],
8327
+ [
8328
+ "amazonqcli",
8329
+ {
8330
+ class: AmazonQCliRule,
8331
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8332
+ }
8333
+ ],
8334
+ [
8335
+ "antigravity",
8336
+ {
8337
+ class: AntigravityRule,
8338
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8339
+ }
8340
+ ],
8341
+ [
8342
+ "augmentcode",
8343
+ {
8344
+ class: AugmentcodeRule,
8345
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8346
+ }
8347
+ ],
8348
+ [
8349
+ "augmentcode-legacy",
8350
+ {
8351
+ class: AugmentcodeLegacyRule,
8352
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8353
+ }
8354
+ ],
8355
+ [
8356
+ "claudecode",
8357
+ {
8358
+ class: ClaudecodeRule,
8359
+ meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "auto" }
8360
+ }
8361
+ ],
8362
+ [
8363
+ "claudecode-legacy",
8364
+ {
8365
+ class: ClaudecodeLegacyRule,
8366
+ meta: { extension: "md", supportsGlobal: true, ruleDiscoveryMode: "claudecode-legacy" }
8367
+ }
8368
+ ],
8369
+ [
8370
+ "cline",
8371
+ {
8372
+ class: ClineRule,
8373
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8374
+ }
8375
+ ],
8376
+ [
8377
+ "codexcli",
8378
+ {
8379
+ class: CodexcliRule,
8380
+ meta: {
8381
+ extension: "md",
8382
+ supportsGlobal: true,
8383
+ ruleDiscoveryMode: "toon",
8384
+ additionalConventions: {
8385
+ subagents: { subagentClass: CodexCliSubagent },
8386
+ skills: { skillClass: CodexCliSkill, globalOnly: true }
8387
+ }
8388
+ }
8389
+ }
8390
+ ],
8391
+ [
8392
+ "copilot",
8393
+ {
8394
+ class: CopilotRule,
8395
+ meta: {
8396
+ extension: "md",
8397
+ supportsGlobal: false,
8398
+ ruleDiscoveryMode: "auto",
8399
+ additionalConventions: {
8400
+ commands: { commandClass: CopilotCommand },
8401
+ subagents: { subagentClass: CopilotSubagent },
8402
+ skills: { skillClass: CopilotSkill }
8403
+ }
8404
+ }
8405
+ }
8406
+ ],
8407
+ [
8408
+ "cursor",
8409
+ {
8410
+ class: CursorRule,
8411
+ meta: {
8412
+ extension: "mdc",
8413
+ supportsGlobal: false,
8414
+ ruleDiscoveryMode: "auto",
8415
+ additionalConventions: {
8416
+ commands: { commandClass: CursorCommand },
8417
+ subagents: { subagentClass: CursorSubagent },
8418
+ skills: { skillClass: CursorSkill }
8419
+ },
8420
+ createsSeparateConventionsRule: true
8421
+ }
8422
+ }
8423
+ ],
8424
+ [
8425
+ "geminicli",
8426
+ {
8427
+ class: GeminiCliRule,
8428
+ meta: {
8429
+ extension: "md",
8430
+ supportsGlobal: true,
8431
+ ruleDiscoveryMode: "toon",
8432
+ additionalConventions: {
8433
+ commands: { commandClass: GeminiCliCommand },
8434
+ subagents: { subagentClass: GeminiCliSubagent },
8435
+ skills: { skillClass: GeminiCliSkill }
8436
+ }
8437
+ }
8438
+ }
8439
+ ],
8440
+ [
8441
+ "junie",
8442
+ {
8443
+ class: JunieRule,
8444
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8445
+ }
8446
+ ],
8447
+ [
8448
+ "kiro",
8449
+ {
8450
+ class: KiroRule,
8451
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8452
+ }
8453
+ ],
8454
+ [
8455
+ "opencode",
8456
+ {
8457
+ class: OpenCodeRule,
8458
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8459
+ }
8460
+ ],
8461
+ [
8462
+ "qwencode",
8463
+ {
8464
+ class: QwencodeRule,
8465
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8466
+ }
8467
+ ],
8468
+ [
8469
+ "roo",
8470
+ {
8471
+ class: RooRule,
8472
+ meta: {
8473
+ extension: "md",
8474
+ supportsGlobal: false,
8475
+ ruleDiscoveryMode: "auto",
8476
+ additionalConventions: {
8477
+ commands: { commandClass: RooCommand },
8478
+ subagents: { subagentClass: RooSubagent }
8479
+ },
8480
+ createsSeparateConventionsRule: true
8481
+ }
8482
+ }
8483
+ ],
8484
+ [
8485
+ "warp",
8486
+ {
8487
+ class: WarpRule,
8488
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "toon" }
8489
+ }
8490
+ ],
8491
+ [
8492
+ "windsurf",
8493
+ {
8494
+ class: WindsurfRule,
8495
+ meta: { extension: "md", supportsGlobal: false, ruleDiscoveryMode: "auto" }
8496
+ }
8497
+ ]
8011
8498
  ]);
8499
+ var rulesProcessorToolTargetsGlobal = Array.from(toolRuleFactories.entries()).filter(([_, factory]) => factory.meta.supportsGlobal).map(([target]) => target);
8012
8500
  var defaultGetFactory6 = (target) => {
8013
8501
  const factory = toolRuleFactories.get(target);
8014
8502
  if (!factory) {
@@ -8023,6 +8511,7 @@ var RulesProcessor = class extends FeatureProcessor {
8023
8511
  simulateSkills;
8024
8512
  global;
8025
8513
  getFactory;
8514
+ skills;
8026
8515
  constructor({
8027
8516
  baseDir = process.cwd(),
8028
8517
  toolTarget,
@@ -8030,7 +8519,8 @@ var RulesProcessor = class extends FeatureProcessor {
8030
8519
  simulateSubagents = false,
8031
8520
  simulateSkills = false,
8032
8521
  global = false,
8033
- getFactory = defaultGetFactory6
8522
+ getFactory = defaultGetFactory6,
8523
+ skills
8034
8524
  }) {
8035
8525
  super({ baseDir });
8036
8526
  const result = RulesProcessorToolTargetSchema.safeParse(toolTarget);
@@ -8045,12 +8535,14 @@ var RulesProcessor = class extends FeatureProcessor {
8045
8535
  this.simulateSubagents = simulateSubagents;
8046
8536
  this.simulateSkills = simulateSkills;
8047
8537
  this.getFactory = getFactory;
8538
+ this.skills = skills;
8048
8539
  }
8049
8540
  async convertRulesyncFilesToToolFiles(rulesyncFiles) {
8050
8541
  const rulesyncRules = rulesyncFiles.filter(
8051
8542
  (file) => file instanceof RulesyncRule
8052
8543
  );
8053
8544
  const factory = this.getFactory(this.toolTarget);
8545
+ const { meta } = factory;
8054
8546
  const toolRules = rulesyncRules.map((rulesyncRule) => {
8055
8547
  if (!factory.class.isTargetedByRulesyncRule(rulesyncRule)) {
8056
8548
  return null;
@@ -8063,153 +8555,105 @@ var RulesProcessor = class extends FeatureProcessor {
8063
8555
  });
8064
8556
  }).filter((rule) => rule !== null);
8065
8557
  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
- );
8558
+ if (isSimulated && meta.createsSeparateConventionsRule && meta.additionalConventions) {
8559
+ const conventionsContent = this.generateAdditionalConventionsSectionFromMeta(meta);
8560
+ const settablePaths = factory.class.getSettablePaths();
8561
+ const nonRootPath = "nonRoot" in settablePaths ? settablePaths.nonRoot : null;
8562
+ if (nonRootPath) {
8563
+ toolRules.push(
8564
+ factory.class.fromRulesyncRule({
8565
+ baseDir: this.baseDir,
8566
+ rulesyncRule: new RulesyncRule({
8567
+ baseDir: this.baseDir,
8568
+ relativeDirPath: nonRootPath.relativeDirPath,
8569
+ relativeFilePath: "additional-conventions.md",
8570
+ frontmatter: {
8571
+ root: false,
8572
+ targets: [this.toolTarget]
8573
+ },
8574
+ body: conventionsContent
8575
+ }),
8576
+ validate: true,
8577
+ global: this.global
8578
+ })
8579
+ );
8580
+ }
8103
8581
  }
8104
8582
  const rootRuleIndex = toolRules.findIndex((rule) => rule.isRoot());
8105
8583
  if (rootRuleIndex === -1) {
8106
8584
  return toolRules;
8107
8585
  }
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
- }
8586
+ const rootRule = toolRules[rootRuleIndex];
8587
+ if (!rootRule) {
8588
+ return toolRules;
8589
+ }
8590
+ const referenceSection = this.generateReferenceSectionFromMeta(meta, toolRules);
8591
+ const conventionsSection = !meta.createsSeparateConventionsRule && meta.additionalConventions ? this.generateAdditionalConventionsSectionFromMeta(meta) : "";
8592
+ const newContent = referenceSection + conventionsSection + rootRule.getFileContent();
8593
+ rootRule.setFileContent(newContent);
8594
+ return toolRules;
8595
+ }
8596
+ buildSkillList(skillClass) {
8597
+ if (!this.skills) return [];
8598
+ const toolRelativeDirPath = skillClass.getSettablePaths({
8599
+ global: this.global
8600
+ }).relativeDirPath;
8601
+ return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
8602
+ const frontmatter = skill.getFrontmatter();
8603
+ const relativePath = join82(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
8604
+ return {
8605
+ name: frontmatter.name,
8606
+ description: frontmatter.description,
8607
+ path: relativePath
8608
+ };
8609
+ });
8610
+ }
8611
+ /**
8612
+ * Generate reference section based on meta configuration.
8613
+ */
8614
+ generateReferenceSectionFromMeta(meta, toolRules) {
8615
+ switch (meta.ruleDiscoveryMode) {
8616
+ case "toon":
8617
+ return this.generateToonReferencesSection(toolRules);
8618
+ case "claudecode-legacy":
8619
+ return this.generateReferencesSection(toolRules);
8620
+ case "auto":
8210
8621
  default:
8211
- return toolRules;
8622
+ return "";
8623
+ }
8624
+ }
8625
+ /**
8626
+ * Generate additional conventions section based on meta configuration.
8627
+ */
8628
+ generateAdditionalConventionsSectionFromMeta(meta) {
8629
+ const { additionalConventions } = meta;
8630
+ if (!additionalConventions) {
8631
+ return "";
8632
+ }
8633
+ const conventions = {};
8634
+ if (additionalConventions.commands) {
8635
+ const { commandClass } = additionalConventions.commands;
8636
+ const relativeDirPath = commandClass.getSettablePaths({
8637
+ global: this.global
8638
+ }).relativeDirPath;
8639
+ conventions.commands = { relativeDirPath };
8212
8640
  }
8641
+ if (additionalConventions.subagents) {
8642
+ const { subagentClass } = additionalConventions.subagents;
8643
+ const relativeDirPath = subagentClass.getSettablePaths({
8644
+ global: this.global
8645
+ }).relativeDirPath;
8646
+ conventions.subagents = { relativeDirPath };
8647
+ }
8648
+ if (additionalConventions.skills) {
8649
+ const { skillClass, globalOnly } = additionalConventions.skills;
8650
+ if (!globalOnly || this.global) {
8651
+ conventions.skills = {
8652
+ skillList: this.buildSkillList(skillClass)
8653
+ };
8654
+ }
8655
+ }
8656
+ return this.generateAdditionalConventionsSection(conventions);
8213
8657
  }
8214
8658
  async convertToolFilesToRulesyncFiles(toolFiles) {
8215
8659
  const toolRules = toolFiles.filter((file) => file instanceof ToolRule);
@@ -8394,15 +8838,7 @@ Simulated subagents are specialized AI assistants that can be invoked to handle
8394
8838
  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
8839
 
8396
8840
  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.` : "";
8841
+ const skillsSection = skills ? this.generateSkillsSection(skills) : "";
8406
8842
  const result = [
8407
8843
  overview,
8408
8844
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
@@ -8411,6 +8847,21 @@ Additionally, you should proactively consider using available skills when they w
8411
8847
  ].join("\n\n") + "\n\n";
8412
8848
  return result;
8413
8849
  }
8850
+ generateSkillsSection(skills) {
8851
+ if (!skills.skillList || skills.skillList.length === 0) {
8852
+ return "";
8853
+ }
8854
+ const skillListWithAtPrefix = skills.skillList.map((skill) => ({
8855
+ ...skill,
8856
+ path: `@${skill.path}`
8857
+ }));
8858
+ const toonContent = encode({ skillList: skillListWithAtPrefix });
8859
+ return `## Simulated Skills
8860
+
8861
+ 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.
8862
+
8863
+ ${toonContent}`;
8864
+ }
8414
8865
  };
8415
8866
 
8416
8867
  // src/cli/commands/generate.ts
@@ -8423,13 +8874,15 @@ async function generateCommand(options) {
8423
8874
  process.exit(1);
8424
8875
  }
8425
8876
  logger.info(`Base directories: ${config.getBaseDirs().join(", ")}`);
8426
- const totalRulesOutputs = await generateRules(config);
8427
8877
  const totalIgnoreOutputs = await generateIgnore(config);
8428
8878
  const totalMcpOutputs = await generateMcp(config);
8429
8879
  const totalCommandOutputs = await generateCommands(config);
8430
8880
  const totalSubagentOutputs = await generateSubagents(config);
8431
- const totalSkillOutputs = await generateSkills(config);
8432
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
8881
+ const skillsResult = await generateSkills(config);
8882
+ const totalRulesOutputs = await generateRules(config, {
8883
+ skills: skillsResult.skills
8884
+ });
8885
+ const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + skillsResult.totalOutputs;
8433
8886
  if (totalGenerated === 0) {
8434
8887
  const enabledFeatures = config.getFeatures().join(", ");
8435
8888
  logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
@@ -8442,11 +8895,11 @@ async function generateCommand(options) {
8442
8895
  if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
8443
8896
  if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
8444
8897
  if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
8445
- if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
8898
+ if (skillsResult.totalOutputs > 0) parts.push(`${skillsResult.totalOutputs} skills`);
8446
8899
  logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
8447
8900
  }
8448
8901
  }
8449
- async function generateRules(config) {
8902
+ async function generateRules(config, options) {
8450
8903
  if (!config.getFeatures().includes("rules")) {
8451
8904
  logger.debug("Skipping rule generation (not in --features)");
8452
8905
  return 0;
@@ -8465,7 +8918,8 @@ async function generateRules(config) {
8465
8918
  global: config.getGlobal(),
8466
8919
  simulateCommands: config.getSimulateCommands(),
8467
8920
  simulateSubagents: config.getSimulateSubagents(),
8468
- simulateSkills: config.getSimulateSkills()
8921
+ simulateSkills: config.getSimulateSkills(),
8922
+ skills: options?.skills
8469
8923
  });
8470
8924
  if (config.getDelete()) {
8471
8925
  const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
@@ -8629,9 +9083,10 @@ async function generateSubagents(config) {
8629
9083
  async function generateSkills(config) {
8630
9084
  if (!config.getFeatures().includes("skills")) {
8631
9085
  logger.debug("Skipping skill generation (not in --features)");
8632
- return 0;
9086
+ return { totalOutputs: 0, skills: [] };
8633
9087
  }
8634
9088
  let totalSkillOutputs = 0;
9089
+ const allSkills = [];
8635
9090
  logger.info("Generating skill files...");
8636
9091
  const toolTargets = intersection(
8637
9092
  config.getTargets(),
@@ -8652,13 +9107,18 @@ async function generateSkills(config) {
8652
9107
  await processor.removeAiDirs(oldToolDirs);
8653
9108
  }
8654
9109
  const rulesyncDirs = await processor.loadRulesyncDirs();
9110
+ for (const rulesyncDir of rulesyncDirs) {
9111
+ if (rulesyncDir instanceof RulesyncSkill) {
9112
+ allSkills.push(rulesyncDir);
9113
+ }
9114
+ }
8655
9115
  const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
8656
9116
  const writtenCount = await processor.writeAiDirs(toolDirs);
8657
9117
  totalSkillOutputs += writtenCount;
8658
9118
  logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
8659
9119
  }
8660
9120
  }
8661
- return totalSkillOutputs;
9121
+ return { totalOutputs: totalSkillOutputs, skills: allSkills };
8662
9122
  }
8663
9123
 
8664
9124
  // src/cli/commands/gitignore.ts
@@ -9195,7 +9655,7 @@ import { FastMCP } from "fastmcp";
9195
9655
 
9196
9656
  // src/mcp/commands.ts
9197
9657
  import { basename as basename22, join as join85 } from "path";
9198
- import { z as z34 } from "zod/mini";
9658
+ import { z as z35 } from "zod/mini";
9199
9659
  var maxCommandSizeBytes = 1024 * 1024;
9200
9660
  var maxCommandsCount = 1e3;
9201
9661
  async function listCommands() {
@@ -9314,17 +9774,17 @@ async function deleteCommand({ relativePathFromCwd }) {
9314
9774
  }
9315
9775
  }
9316
9776
  var commandToolSchemas = {
9317
- listCommands: z34.object({}),
9318
- getCommand: z34.object({
9319
- relativePathFromCwd: z34.string()
9777
+ listCommands: z35.object({}),
9778
+ getCommand: z35.object({
9779
+ relativePathFromCwd: z35.string()
9320
9780
  }),
9321
- putCommand: z34.object({
9322
- relativePathFromCwd: z34.string(),
9781
+ putCommand: z35.object({
9782
+ relativePathFromCwd: z35.string(),
9323
9783
  frontmatter: RulesyncCommandFrontmatterSchema,
9324
- body: z34.string()
9784
+ body: z35.string()
9325
9785
  }),
9326
- deleteCommand: z34.object({
9327
- relativePathFromCwd: z34.string()
9786
+ deleteCommand: z35.object({
9787
+ relativePathFromCwd: z35.string()
9328
9788
  })
9329
9789
  };
9330
9790
  var commandTools = {
@@ -9373,7 +9833,7 @@ var commandTools = {
9373
9833
 
9374
9834
  // src/mcp/ignore.ts
9375
9835
  import { join as join86 } from "path";
9376
- import { z as z35 } from "zod/mini";
9836
+ import { z as z36 } from "zod/mini";
9377
9837
  var maxIgnoreFileSizeBytes = 100 * 1024;
9378
9838
  async function getIgnoreFile() {
9379
9839
  const ignoreFilePath = join86(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
@@ -9430,11 +9890,11 @@ async function deleteIgnoreFile() {
9430
9890
  }
9431
9891
  }
9432
9892
  var ignoreToolSchemas = {
9433
- getIgnoreFile: z35.object({}),
9434
- putIgnoreFile: z35.object({
9435
- content: z35.string()
9893
+ getIgnoreFile: z36.object({}),
9894
+ putIgnoreFile: z36.object({
9895
+ content: z36.string()
9436
9896
  }),
9437
- deleteIgnoreFile: z35.object({})
9897
+ deleteIgnoreFile: z36.object({})
9438
9898
  };
9439
9899
  var ignoreTools = {
9440
9900
  getIgnoreFile: {
@@ -9468,7 +9928,7 @@ var ignoreTools = {
9468
9928
 
9469
9929
  // src/mcp/mcp.ts
9470
9930
  import { join as join87 } from "path";
9471
- import { z as z36 } from "zod/mini";
9931
+ import { z as z37 } from "zod/mini";
9472
9932
  var maxMcpSizeBytes = 1024 * 1024;
9473
9933
  async function getMcpFile() {
9474
9934
  const config = await ConfigResolver.resolve({});
@@ -9558,11 +10018,11 @@ async function deleteMcpFile() {
9558
10018
  }
9559
10019
  }
9560
10020
  var mcpToolSchemas = {
9561
- getMcpFile: z36.object({}),
9562
- putMcpFile: z36.object({
9563
- content: z36.string()
10021
+ getMcpFile: z37.object({}),
10022
+ putMcpFile: z37.object({
10023
+ content: z37.string()
9564
10024
  }),
9565
- deleteMcpFile: z36.object({})
10025
+ deleteMcpFile: z37.object({})
9566
10026
  };
9567
10027
  var mcpTools = {
9568
10028
  getMcpFile: {
@@ -9596,7 +10056,7 @@ var mcpTools = {
9596
10056
 
9597
10057
  // src/mcp/rules.ts
9598
10058
  import { basename as basename23, join as join88 } from "path";
9599
- import { z as z37 } from "zod/mini";
10059
+ import { z as z38 } from "zod/mini";
9600
10060
  var maxRuleSizeBytes = 1024 * 1024;
9601
10061
  var maxRulesCount = 1e3;
9602
10062
  async function listRules() {
@@ -9715,17 +10175,17 @@ async function deleteRule({ relativePathFromCwd }) {
9715
10175
  }
9716
10176
  }
9717
10177
  var ruleToolSchemas = {
9718
- listRules: z37.object({}),
9719
- getRule: z37.object({
9720
- relativePathFromCwd: z37.string()
10178
+ listRules: z38.object({}),
10179
+ getRule: z38.object({
10180
+ relativePathFromCwd: z38.string()
9721
10181
  }),
9722
- putRule: z37.object({
9723
- relativePathFromCwd: z37.string(),
10182
+ putRule: z38.object({
10183
+ relativePathFromCwd: z38.string(),
9724
10184
  frontmatter: RulesyncRuleFrontmatterSchema,
9725
- body: z37.string()
10185
+ body: z38.string()
9726
10186
  }),
9727
- deleteRule: z37.object({
9728
- relativePathFromCwd: z37.string()
10187
+ deleteRule: z38.object({
10188
+ relativePathFromCwd: z38.string()
9729
10189
  })
9730
10190
  };
9731
10191
  var ruleTools = {
@@ -9774,7 +10234,7 @@ var ruleTools = {
9774
10234
 
9775
10235
  // src/mcp/skills.ts
9776
10236
  import { basename as basename24, dirname as dirname2, join as join89 } from "path";
9777
- import { z as z38 } from "zod/mini";
10237
+ import { z as z39 } from "zod/mini";
9778
10238
  var maxSkillSizeBytes = 1024 * 1024;
9779
10239
  var maxSkillsCount = 1e3;
9780
10240
  function aiDirFileToMcpSkillFile(file) {
@@ -9942,23 +10402,23 @@ async function deleteSkill({
9942
10402
  );
9943
10403
  }
9944
10404
  }
9945
- var McpSkillFileSchema = z38.object({
9946
- name: z38.string(),
9947
- body: z38.string()
10405
+ var McpSkillFileSchema = z39.object({
10406
+ name: z39.string(),
10407
+ body: z39.string()
9948
10408
  });
9949
10409
  var skillToolSchemas = {
9950
- listSkills: z38.object({}),
9951
- getSkill: z38.object({
9952
- relativeDirPathFromCwd: z38.string()
10410
+ listSkills: z39.object({}),
10411
+ getSkill: z39.object({
10412
+ relativeDirPathFromCwd: z39.string()
9953
10413
  }),
9954
- putSkill: z38.object({
9955
- relativeDirPathFromCwd: z38.string(),
10414
+ putSkill: z39.object({
10415
+ relativeDirPathFromCwd: z39.string(),
9956
10416
  frontmatter: RulesyncSkillFrontmatterSchema,
9957
- body: z38.string(),
9958
- otherFiles: z38.optional(z38.array(McpSkillFileSchema))
10417
+ body: z39.string(),
10418
+ otherFiles: z39.optional(z39.array(McpSkillFileSchema))
9959
10419
  }),
9960
- deleteSkill: z38.object({
9961
- relativeDirPathFromCwd: z38.string()
10420
+ deleteSkill: z39.object({
10421
+ relativeDirPathFromCwd: z39.string()
9962
10422
  })
9963
10423
  };
9964
10424
  var skillTools = {
@@ -10008,7 +10468,7 @@ var skillTools = {
10008
10468
 
10009
10469
  // src/mcp/subagents.ts
10010
10470
  import { basename as basename25, join as join90 } from "path";
10011
- import { z as z39 } from "zod/mini";
10471
+ import { z as z40 } from "zod/mini";
10012
10472
  var maxSubagentSizeBytes = 1024 * 1024;
10013
10473
  var maxSubagentsCount = 1e3;
10014
10474
  async function listSubagents() {
@@ -10132,17 +10592,17 @@ async function deleteSubagent({ relativePathFromCwd }) {
10132
10592
  }
10133
10593
  }
10134
10594
  var subagentToolSchemas = {
10135
- listSubagents: z39.object({}),
10136
- getSubagent: z39.object({
10137
- relativePathFromCwd: z39.string()
10595
+ listSubagents: z40.object({}),
10596
+ getSubagent: z40.object({
10597
+ relativePathFromCwd: z40.string()
10138
10598
  }),
10139
- putSubagent: z39.object({
10140
- relativePathFromCwd: z39.string(),
10599
+ putSubagent: z40.object({
10600
+ relativePathFromCwd: z40.string(),
10141
10601
  frontmatter: RulesyncSubagentFrontmatterSchema,
10142
- body: z39.string()
10602
+ body: z40.string()
10143
10603
  }),
10144
- deleteSubagent: z39.object({
10145
- relativePathFromCwd: z39.string()
10604
+ deleteSubagent: z40.object({
10605
+ relativePathFromCwd: z40.string()
10146
10606
  })
10147
10607
  };
10148
10608
  var subagentTools = {
@@ -10226,7 +10686,7 @@ async function mcpCommand({ version }) {
10226
10686
  }
10227
10687
 
10228
10688
  // src/cli/index.ts
10229
- var getVersion = () => "3.32.0";
10689
+ var getVersion = () => "3.34.0";
10230
10690
  var main = async () => {
10231
10691
  const program = new Command();
10232
10692
  const version = getVersion();