rulesync 7.23.0 → 7.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -61,6 +61,7 @@ var ALL_TOOL_TARGETS = [
61
61
  "qwencode",
62
62
  "replit",
63
63
  "roo",
64
+ "rovodev",
64
65
  "warp",
65
66
  "windsurf",
66
67
  "zed"
@@ -75,7 +76,8 @@ import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
75
76
  import { parse as parseJsonc } from "jsonc-parser";
76
77
 
77
78
  // src/constants/rulesync-paths.ts
78
- import { join } from "path";
79
+ import { posix } from "path";
80
+ var { join } = posix;
79
81
  var RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
80
82
  var RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH = "rulesync.local.jsonc";
81
83
  var RULESYNC_RELATIVE_DIR_PATH = ".rulesync";
@@ -135,6 +137,9 @@ async function readOrInitializeFileContent(filePath, initialContent = "") {
135
137
  return initialContent;
136
138
  }
137
139
  }
140
+ function toPosixPath(p) {
141
+ return p.replace(/\\/g, "/");
142
+ }
138
143
  function checkPathTraversal({
139
144
  relativePath,
140
145
  intendedRootDir
@@ -602,83 +607,19 @@ function getBaseDirsInLightOfGlobal({
602
607
  }
603
608
 
604
609
  // src/lib/generate.ts
605
- import { join as join123 } from "path";
610
+ import { join as join127 } from "path";
606
611
  import { intersection } from "es-toolkit";
607
612
 
608
613
  // src/features/commands/commands-processor.ts
609
614
  import { basename as basename2, join as join20, relative as relative3 } from "path";
610
615
  import { z as z14 } from "zod/mini";
611
616
 
612
- // src/types/feature-processor.ts
613
- var FeatureProcessor = class {
614
- baseDir;
615
- dryRun;
616
- logger;
617
- constructor({
618
- baseDir = process.cwd(),
619
- dryRun = false,
620
- logger
621
- }) {
622
- this.baseDir = baseDir;
623
- this.dryRun = dryRun;
624
- this.logger = logger;
625
- }
626
- /**
627
- * Return tool targets that this feature supports.
628
- */
629
- static getToolTargets(_params = {}) {
630
- throw new Error("Not implemented");
631
- }
632
- /**
633
- * Once converted to rulesync/tool files, write them to the filesystem.
634
- * Returns the count and paths of files written.
635
- */
636
- async writeAiFiles(aiFiles) {
637
- let changedCount = 0;
638
- const changedPaths = [];
639
- for (const aiFile of aiFiles) {
640
- const filePath = aiFile.getFilePath();
641
- const contentWithNewline = addTrailingNewline(aiFile.getFileContent());
642
- const existingContent = await readFileContentOrNull(filePath);
643
- if (existingContent === contentWithNewline) {
644
- continue;
645
- }
646
- if (this.dryRun) {
647
- this.logger.info(`[DRY RUN] Would write: ${filePath}`);
648
- } else {
649
- await writeFileContent(filePath, contentWithNewline);
650
- }
651
- changedCount++;
652
- changedPaths.push(aiFile.getRelativePathFromCwd());
653
- }
654
- return { count: changedCount, paths: changedPaths };
655
- }
656
- async removeAiFiles(aiFiles) {
657
- for (const aiFile of aiFiles) {
658
- await removeFile(aiFile.getFilePath());
659
- }
660
- }
661
- /**
662
- * Remove orphan files that exist in the tool directory but not in the generated files.
663
- * This only deletes files that are no longer in the rulesync source, not files that will be overwritten.
664
- */
665
- async removeOrphanAiFiles(existingFiles, generatedFiles) {
666
- const generatedPaths = new Set(generatedFiles.map((f) => f.getFilePath()));
667
- const orphanFiles = existingFiles.filter((f) => !generatedPaths.has(f.getFilePath()));
668
- for (const aiFile of orphanFiles) {
669
- const filePath = aiFile.getFilePath();
670
- if (this.dryRun) {
671
- this.logger.info(`[DRY RUN] Would delete: ${filePath}`);
672
- } else {
673
- await removeFile(filePath);
674
- }
675
- }
676
- return orphanFiles.length;
677
- }
678
- };
679
-
680
- // src/features/commands/agentsmd-command.ts
681
- import { join as join5 } from "path";
617
+ // src/utils/content-equivalence.ts
618
+ import { extname } from "path";
619
+ import { isDeepStrictEqual } from "util";
620
+ import { load as load2 } from "js-yaml";
621
+ import { parse as parseJsonc2 } from "jsonc-parser";
622
+ import * as smolToml from "smol-toml";
682
623
 
683
624
  // src/utils/frontmatter.ts
684
625
  import matter from "gray-matter";
@@ -791,6 +732,154 @@ function parseFrontmatter(content, filePath) {
791
732
  return { frontmatter: cleanFrontmatter, body };
792
733
  }
793
734
 
735
+ // src/utils/content-equivalence.ts
736
+ function tryJsonEquivalent(a, b) {
737
+ const errorsA = [];
738
+ const errorsB = [];
739
+ const parsedA = parseJsonc2(a, errorsA);
740
+ const parsedB = parseJsonc2(b, errorsB);
741
+ if (errorsA.length > 0 || errorsB.length > 0) {
742
+ return void 0;
743
+ }
744
+ return isDeepStrictEqual(parsedA, parsedB);
745
+ }
746
+ function tryYamlEquivalent(a, b) {
747
+ try {
748
+ return isDeepStrictEqual(load2(a), load2(b));
749
+ } catch {
750
+ return void 0;
751
+ }
752
+ }
753
+ function tryTomlEquivalent(a, b) {
754
+ try {
755
+ return isDeepStrictEqual(smolToml.parse(a), smolToml.parse(b));
756
+ } catch {
757
+ return void 0;
758
+ }
759
+ }
760
+ function tryMarkdownEquivalent(expected, existing) {
761
+ function normalizeMarkdownBody(body) {
762
+ return addTrailingNewline(body.replace(/^\n+/, ""));
763
+ }
764
+ try {
765
+ const parsedExpected = parseFrontmatter(expected);
766
+ const parsedExisting = parseFrontmatter(existing);
767
+ if (!isDeepStrictEqual(parsedExpected.frontmatter, parsedExisting.frontmatter)) {
768
+ return false;
769
+ }
770
+ return normalizeMarkdownBody(parsedExpected.body) === normalizeMarkdownBody(parsedExisting.body);
771
+ } catch {
772
+ return void 0;
773
+ }
774
+ }
775
+ function tryFileContentsEquivalent(filePath, expected, existing) {
776
+ const ext = extname(filePath).toLowerCase();
777
+ switch (ext) {
778
+ case ".json":
779
+ case ".jsonc":
780
+ return tryJsonEquivalent(expected, existing);
781
+ case ".yaml":
782
+ case ".yml":
783
+ return tryYamlEquivalent(expected, existing);
784
+ case ".toml":
785
+ return tryTomlEquivalent(expected, existing);
786
+ case ".md":
787
+ case ".mdc":
788
+ return tryMarkdownEquivalent(expected, existing);
789
+ default:
790
+ return void 0;
791
+ }
792
+ }
793
+ function fileContentsEquivalent({
794
+ filePath,
795
+ expected,
796
+ existing
797
+ }) {
798
+ if (existing === null) {
799
+ return false;
800
+ }
801
+ const structured = tryFileContentsEquivalent(filePath, expected, existing);
802
+ if (structured !== void 0) {
803
+ return structured;
804
+ }
805
+ return addTrailingNewline(expected) === addTrailingNewline(existing);
806
+ }
807
+
808
+ // src/types/feature-processor.ts
809
+ var FeatureProcessor = class {
810
+ baseDir;
811
+ dryRun;
812
+ logger;
813
+ constructor({
814
+ baseDir = process.cwd(),
815
+ dryRun = false,
816
+ logger
817
+ }) {
818
+ this.baseDir = baseDir;
819
+ this.dryRun = dryRun;
820
+ this.logger = logger;
821
+ }
822
+ /**
823
+ * Return tool targets that this feature supports.
824
+ */
825
+ static getToolTargets(_params = {}) {
826
+ throw new Error("Not implemented");
827
+ }
828
+ /**
829
+ * Once converted to rulesync/tool files, write them to the filesystem.
830
+ * Returns the count and paths of files written.
831
+ */
832
+ async writeAiFiles(aiFiles) {
833
+ let changedCount = 0;
834
+ const changedPaths = [];
835
+ for (const aiFile of aiFiles) {
836
+ const filePath = aiFile.getFilePath();
837
+ const contentWithNewline = addTrailingNewline(aiFile.getFileContent());
838
+ const existingContent = await readFileContentOrNull(filePath);
839
+ if (fileContentsEquivalent({
840
+ filePath,
841
+ expected: contentWithNewline,
842
+ existing: existingContent
843
+ })) {
844
+ continue;
845
+ }
846
+ if (this.dryRun) {
847
+ this.logger.info(`[DRY RUN] Would write: ${filePath}`);
848
+ } else {
849
+ await writeFileContent(filePath, contentWithNewline);
850
+ }
851
+ changedCount++;
852
+ changedPaths.push(aiFile.getRelativePathFromCwd());
853
+ }
854
+ return { count: changedCount, paths: changedPaths };
855
+ }
856
+ async removeAiFiles(aiFiles) {
857
+ for (const aiFile of aiFiles) {
858
+ await removeFile(aiFile.getFilePath());
859
+ }
860
+ }
861
+ /**
862
+ * Remove orphan files that exist in the tool directory but not in the generated files.
863
+ * This only deletes files that are no longer in the rulesync source, not files that will be overwritten.
864
+ */
865
+ async removeOrphanAiFiles(existingFiles, generatedFiles) {
866
+ const generatedPaths = new Set(generatedFiles.map((f) => f.getFilePath()));
867
+ const orphanFiles = existingFiles.filter((f) => !generatedPaths.has(f.getFilePath()));
868
+ for (const aiFile of orphanFiles) {
869
+ const filePath = aiFile.getFilePath();
870
+ if (this.dryRun) {
871
+ this.logger.info(`[DRY RUN] Would delete: ${filePath}`);
872
+ } else {
873
+ await removeFile(filePath);
874
+ }
875
+ }
876
+ return orphanFiles.length;
877
+ }
878
+ };
879
+
880
+ // src/features/commands/agentsmd-command.ts
881
+ import { join as join5 } from "path";
882
+
794
883
  // src/features/commands/simulated-command.ts
795
884
  import { join as join4 } from "path";
796
885
  import { z as z4 } from "zod/mini";
@@ -858,8 +947,11 @@ var AiFile = class {
858
947
  getFileContent() {
859
948
  return this.fileContent;
860
949
  }
950
+ /**
951
+ * Returns the relative path from CWD with POSIX separators for consistent cross-platform output.
952
+ */
861
953
  getRelativePathFromCwd() {
862
- return path.join(this.relativeDirPath, this.relativeFilePath);
954
+ return toPosixPath(path.join(this.relativeDirPath, this.relativeFilePath));
863
955
  }
864
956
  setFileContent(newFileContent) {
865
957
  this.fileContent = newFileContent;
@@ -6057,6 +6149,9 @@ var McpServerSchema = z20.looseObject({
6057
6149
  disabledTools: z20.optional(z20.array(z20.string()))
6058
6150
  });
6059
6151
  var McpServersSchema = z20.record(z20.string(), McpServerSchema);
6152
+ function isMcpServers(value) {
6153
+ return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value);
6154
+ }
6060
6155
 
6061
6156
  // src/features/mcp/rulesync-mcp.ts
6062
6157
  var RulesyncMcpServerSchema = z21.extend(McpServerSchema, {
@@ -6396,7 +6491,7 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
6396
6491
 
6397
6492
  // src/features/mcp/codexcli-mcp.ts
6398
6493
  import { join as join46 } from "path";
6399
- import * as smolToml from "smol-toml";
6494
+ import * as smolToml2 from "smol-toml";
6400
6495
  function convertFromCodexFormat(codexMcp) {
6401
6496
  const result = {};
6402
6497
  for (const [name, config] of Object.entries(codexMcp)) {
@@ -6449,7 +6544,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
6449
6544
  ...rest,
6450
6545
  validate: false
6451
6546
  });
6452
- this.toml = smolToml.parse(this.fileContent);
6547
+ this.toml = smolToml2.parse(this.fileContent);
6453
6548
  if (rest.validate) {
6454
6549
  const result = this.validate();
6455
6550
  if (!result.success) {
@@ -6478,7 +6573,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
6478
6573
  global = false
6479
6574
  }) {
6480
6575
  const paths = this.getSettablePaths({ global });
6481
- const fileContent = await readFileContentOrNull(join46(baseDir, paths.relativeDirPath, paths.relativeFilePath)) ?? smolToml.stringify({});
6576
+ const fileContent = await readFileContentOrNull(join46(baseDir, paths.relativeDirPath, paths.relativeFilePath)) ?? smolToml2.stringify({});
6482
6577
  return new _CodexcliMcp({
6483
6578
  baseDir,
6484
6579
  relativeDirPath: paths.relativeDirPath,
@@ -6497,9 +6592,9 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
6497
6592
  const configTomlFilePath = join46(baseDir, paths.relativeDirPath, paths.relativeFilePath);
6498
6593
  const configTomlFileContent = await readOrInitializeFileContent(
6499
6594
  configTomlFilePath,
6500
- smolToml.stringify({})
6595
+ smolToml2.stringify({})
6501
6596
  );
6502
- const configToml = smolToml.parse(configTomlFileContent);
6597
+ const configToml = smolToml2.parse(configTomlFileContent);
6503
6598
  const mcpServers = rulesyncMcp.getJson().mcpServers;
6504
6599
  const converted = convertToCodexFormat(mcpServers);
6505
6600
  const filteredMcpServers = this.removeEmptyEntries(converted);
@@ -6508,7 +6603,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
6508
6603
  baseDir,
6509
6604
  relativeDirPath: paths.relativeDirPath,
6510
6605
  relativeFilePath: paths.relativeFilePath,
6511
- fileContent: smolToml.stringify(configToml),
6606
+ fileContent: smolToml2.stringify(configToml),
6512
6607
  validate
6513
6608
  });
6514
6609
  }
@@ -6651,11 +6746,13 @@ function addTypeField(mcpServers) {
6651
6746
  command = cmd;
6652
6747
  args = cmdArgs.length > 0 ? [...cmdArgs, ...parsed.args ?? []] : parsed.args;
6653
6748
  }
6749
+ const serverRecord = server;
6654
6750
  result[name] = {
6655
- type: "stdio",
6751
+ ...serverRecord,
6752
+ ...parsed,
6753
+ type: parsed.type ?? "stdio",
6656
6754
  command,
6657
- ...args && { args },
6658
- ...parsed.env && { env: parsed.env }
6755
+ ...args && { args }
6659
6756
  };
6660
6757
  }
6661
6758
  return result;
@@ -6767,9 +6864,6 @@ var CopilotcliMcp = class _CopilotcliMcp extends ToolMcp {
6767
6864
  // src/features/mcp/cursor-mcp.ts
6768
6865
  import { join as join49 } from "path";
6769
6866
  var CURSOR_ENV_VAR_PATTERN = /\$\{env:([^}]+)\}/g;
6770
- function isMcpServers(value) {
6771
- return value !== void 0 && value !== null && typeof value === "object";
6772
- }
6773
6867
  function convertEnvFromCursorFormat(mcpServers) {
6774
6868
  return Object.fromEntries(
6775
6869
  Object.entries(mcpServers).map(([name, config]) => [
@@ -7386,7 +7480,7 @@ var KiroMcp = class _KiroMcp extends ToolMcp {
7386
7480
 
7387
7481
  // src/features/mcp/opencode-mcp.ts
7388
7482
  import { join as join56 } from "path";
7389
- import { parse as parseJsonc2 } from "jsonc-parser";
7483
+ import { parse as parseJsonc3 } from "jsonc-parser";
7390
7484
  import { z as z22 } from "zod/mini";
7391
7485
  var OpencodeMcpLocalServerSchema = z22.object({
7392
7486
  type: z22.literal("local"),
@@ -7512,7 +7606,7 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
7512
7606
  json;
7513
7607
  constructor(params) {
7514
7608
  super(params);
7515
- this.json = OpencodeConfigSchema.parse(parseJsonc2(this.fileContent || "{}"));
7609
+ this.json = OpencodeConfigSchema.parse(parseJsonc3(this.fileContent || "{}"));
7516
7610
  }
7517
7611
  getJson() {
7518
7612
  return this.json;
@@ -7554,7 +7648,7 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
7554
7648
  }
7555
7649
  }
7556
7650
  const fileContentToUse = fileContent ?? '{"mcp":{}}';
7557
- const json = parseJsonc2(fileContentToUse);
7651
+ const json = parseJsonc3(fileContentToUse);
7558
7652
  const newJson = { ...json, mcp: json.mcp ?? {} };
7559
7653
  return new _OpencodeMcp({
7560
7654
  baseDir,
@@ -7586,7 +7680,7 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
7586
7680
  if (!fileContent) {
7587
7681
  fileContent = JSON.stringify({ mcp: {} }, null, 2);
7588
7682
  }
7589
- const json = parseJsonc2(fileContent);
7683
+ const json = parseJsonc3(fileContent);
7590
7684
  const { mcp: convertedMcp, tools: mcpTools } = convertToOpencodeFormat(
7591
7685
  rulesyncMcp.getMcpServers()
7592
7686
  );
@@ -7637,9 +7731,6 @@ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
7637
7731
 
7638
7732
  // src/features/mcp/roo-mcp.ts
7639
7733
  import { join as join57 } from "path";
7640
- function isRooMcpServers(value) {
7641
- return value !== void 0 && value !== null && typeof value === "object";
7642
- }
7643
7734
  function convertToRooFormat(mcpServers) {
7644
7735
  return Object.fromEntries(
7645
7736
  Object.entries(mcpServers).map(([serverName, serverConfig]) => {
@@ -7655,13 +7746,16 @@ function convertToRooFormat(mcpServers) {
7655
7746
  );
7656
7747
  }
7657
7748
  function convertFromRooFormat(mcpServers) {
7749
+ if (!isMcpServers(mcpServers)) {
7750
+ return {};
7751
+ }
7658
7752
  return Object.fromEntries(
7659
7753
  Object.entries(mcpServers).map(([serverName, serverConfig]) => {
7660
- const converted = { ...serverConfig };
7661
- if (serverConfig.type === "streamable-http") {
7754
+ const converted = typeof serverConfig === "object" && serverConfig !== null && !Array.isArray(serverConfig) ? Object.fromEntries(Object.entries(serverConfig)) : {};
7755
+ if (converted.type === "streamable-http") {
7662
7756
  converted.type = "http";
7663
7757
  }
7664
- if (serverConfig.transport === "streamable-http") {
7758
+ if (converted.transport === "streamable-http") {
7665
7759
  converted.transport = "http";
7666
7760
  }
7667
7761
  return [serverName, converted];
@@ -7719,8 +7813,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
7719
7813
  });
7720
7814
  }
7721
7815
  toRulesyncMcp() {
7722
- const rawMcpServers = isRooMcpServers(this.json.mcpServers) ? this.json.mcpServers : {};
7723
- const convertedMcpServers = convertFromRooFormat(rawMcpServers);
7816
+ const convertedMcpServers = convertFromRooFormat(this.json.mcpServers);
7724
7817
  return this.toRulesyncMcpDefault({
7725
7818
  fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
7726
7819
  });
@@ -7743,63 +7836,182 @@ var RooMcp = class _RooMcp extends ToolMcp {
7743
7836
  }
7744
7837
  };
7745
7838
 
7746
- // src/features/mcp/mcp-processor.ts
7747
- var mcpProcessorToolTargetTuple = [
7748
- "claudecode",
7749
- "claudecode-legacy",
7750
- "cline",
7751
- "codexcli",
7752
- "copilot",
7753
- "copilotcli",
7754
- "cursor",
7755
- "deepagents",
7756
- "factorydroid",
7757
- "geminicli",
7758
- "kilo",
7759
- "kiro",
7760
- "junie",
7761
- "opencode",
7762
- "roo"
7763
- ];
7764
- var McpProcessorToolTargetSchema = z23.enum(mcpProcessorToolTargetTuple);
7765
- var toolMcpFactories = /* @__PURE__ */ new Map([
7766
- [
7767
- "claudecode",
7768
- {
7769
- class: ClaudecodeMcp,
7770
- meta: {
7771
- supportsProject: true,
7772
- supportsGlobal: true,
7773
- supportsEnabledTools: false,
7774
- supportsDisabledTools: false
7775
- }
7776
- }
7777
- ],
7778
- [
7779
- "claudecode-legacy",
7780
- {
7781
- class: ClaudecodeMcp,
7782
- meta: {
7783
- supportsProject: true,
7784
- supportsGlobal: true,
7785
- supportsEnabledTools: false,
7786
- supportsDisabledTools: false
7787
- }
7788
- }
7789
- ],
7790
- [
7791
- "cline",
7792
- {
7793
- class: ClineMcp,
7794
- meta: {
7795
- supportsProject: true,
7796
- supportsGlobal: false,
7797
- supportsEnabledTools: false,
7798
- supportsDisabledTools: false
7799
- }
7839
+ // src/features/mcp/rovodev-mcp.ts
7840
+ import { join as join58 } from "path";
7841
+ function parseRovodevMcpJson(fileContent, relativeDirPath, relativeFilePath) {
7842
+ const configPath = join58(relativeDirPath, relativeFilePath);
7843
+ let parsed;
7844
+ try {
7845
+ parsed = JSON.parse(fileContent);
7846
+ } catch (error) {
7847
+ throw new Error(`Failed to parse Rovodev MCP config at ${configPath}: ${formatError(error)}`, {
7848
+ cause: error
7849
+ });
7850
+ }
7851
+ if (!isRecord(parsed)) {
7852
+ throw new Error(`Failed to parse Rovodev MCP config at ${configPath}: expected a JSON object`);
7853
+ }
7854
+ return parsed;
7855
+ }
7856
+ var RovodevMcp = class _RovodevMcp extends ToolMcp {
7857
+ json;
7858
+ constructor(params) {
7859
+ super(params);
7860
+ if (this.fileContent !== void 0) {
7861
+ this.json = parseRovodevMcpJson(
7862
+ this.fileContent,
7863
+ this.relativeDirPath,
7864
+ this.relativeFilePath
7865
+ );
7866
+ } else {
7867
+ this.json = {};
7800
7868
  }
7801
- ],
7802
- [
7869
+ }
7870
+ getJson() {
7871
+ return this.json;
7872
+ }
7873
+ isDeletable() {
7874
+ return false;
7875
+ }
7876
+ static getSettablePaths(_options) {
7877
+ return {
7878
+ relativeDirPath: ".rovodev",
7879
+ relativeFilePath: "mcp.json"
7880
+ };
7881
+ }
7882
+ static async fromFile({
7883
+ baseDir = process.cwd(),
7884
+ validate = true,
7885
+ global = false
7886
+ }) {
7887
+ if (!global) {
7888
+ throw new Error("Rovodev MCP is global-only; use --global to sync ~/.rovodev/mcp.json");
7889
+ }
7890
+ const paths = this.getSettablePaths({ global });
7891
+ const filePath = join58(baseDir, paths.relativeDirPath, paths.relativeFilePath);
7892
+ const fileContent = await readFileContentOrNull(filePath) ?? '{"mcpServers":{}}';
7893
+ const json = parseRovodevMcpJson(fileContent, paths.relativeDirPath, paths.relativeFilePath);
7894
+ const newJson = { ...json, mcpServers: json.mcpServers ?? {} };
7895
+ return new _RovodevMcp({
7896
+ baseDir,
7897
+ relativeDirPath: paths.relativeDirPath,
7898
+ relativeFilePath: paths.relativeFilePath,
7899
+ fileContent: JSON.stringify(newJson, null, 2),
7900
+ validate,
7901
+ global
7902
+ });
7903
+ }
7904
+ static async fromRulesyncMcp({
7905
+ baseDir = process.cwd(),
7906
+ rulesyncMcp,
7907
+ validate = true,
7908
+ global = false
7909
+ }) {
7910
+ if (!global) {
7911
+ throw new Error("Rovodev MCP is global-only; use --global to sync ~/.rovodev/mcp.json");
7912
+ }
7913
+ const paths = this.getSettablePaths({ global });
7914
+ const fileContent = await readOrInitializeFileContent(
7915
+ join58(baseDir, paths.relativeDirPath, paths.relativeFilePath),
7916
+ JSON.stringify({ mcpServers: {} }, null, 2)
7917
+ );
7918
+ const json = parseRovodevMcpJson(fileContent, paths.relativeDirPath, paths.relativeFilePath);
7919
+ const rulesyncJson = rulesyncMcp.getJson();
7920
+ const mcpServers = isMcpServers(rulesyncJson.mcpServers) ? rulesyncJson.mcpServers : {};
7921
+ const rovodevConfig = { ...json, mcpServers };
7922
+ return new _RovodevMcp({
7923
+ baseDir,
7924
+ relativeDirPath: paths.relativeDirPath,
7925
+ relativeFilePath: paths.relativeFilePath,
7926
+ fileContent: JSON.stringify(rovodevConfig, null, 2),
7927
+ validate,
7928
+ global
7929
+ });
7930
+ }
7931
+ toRulesyncMcp() {
7932
+ const mcpServers = isMcpServers(this.json.mcpServers) ? this.json.mcpServers : {};
7933
+ return this.toRulesyncMcpDefault({
7934
+ fileContent: JSON.stringify({ mcpServers }, null, 2)
7935
+ });
7936
+ }
7937
+ validate() {
7938
+ return { success: true, error: null };
7939
+ }
7940
+ static forDeletion({
7941
+ baseDir = process.cwd(),
7942
+ relativeDirPath,
7943
+ relativeFilePath,
7944
+ global = false
7945
+ }) {
7946
+ return new _RovodevMcp({
7947
+ baseDir,
7948
+ relativeDirPath,
7949
+ relativeFilePath,
7950
+ fileContent: "{}",
7951
+ validate: false,
7952
+ global
7953
+ });
7954
+ }
7955
+ };
7956
+
7957
+ // src/features/mcp/mcp-processor.ts
7958
+ var mcpProcessorToolTargetTuple = [
7959
+ "claudecode",
7960
+ "claudecode-legacy",
7961
+ "cline",
7962
+ "codexcli",
7963
+ "copilot",
7964
+ "copilotcli",
7965
+ "cursor",
7966
+ "deepagents",
7967
+ "factorydroid",
7968
+ "geminicli",
7969
+ "kilo",
7970
+ "kiro",
7971
+ "junie",
7972
+ "opencode",
7973
+ "roo",
7974
+ "rovodev"
7975
+ ];
7976
+ var McpProcessorToolTargetSchema = z23.enum(mcpProcessorToolTargetTuple);
7977
+ var toolMcpFactories = /* @__PURE__ */ new Map([
7978
+ [
7979
+ "claudecode",
7980
+ {
7981
+ class: ClaudecodeMcp,
7982
+ meta: {
7983
+ supportsProject: true,
7984
+ supportsGlobal: true,
7985
+ supportsEnabledTools: false,
7986
+ supportsDisabledTools: false
7987
+ }
7988
+ }
7989
+ ],
7990
+ [
7991
+ "claudecode-legacy",
7992
+ {
7993
+ class: ClaudecodeMcp,
7994
+ meta: {
7995
+ supportsProject: true,
7996
+ supportsGlobal: true,
7997
+ supportsEnabledTools: false,
7998
+ supportsDisabledTools: false
7999
+ }
8000
+ }
8001
+ ],
8002
+ [
8003
+ "cline",
8004
+ {
8005
+ class: ClineMcp,
8006
+ meta: {
8007
+ supportsProject: true,
8008
+ supportsGlobal: false,
8009
+ supportsEnabledTools: false,
8010
+ supportsDisabledTools: false
8011
+ }
8012
+ }
8013
+ ],
8014
+ [
7803
8015
  "codexcli",
7804
8016
  {
7805
8017
  class: CodexcliMcp,
@@ -7942,6 +8154,18 @@ var toolMcpFactories = /* @__PURE__ */ new Map([
7942
8154
  supportsDisabledTools: false
7943
8155
  }
7944
8156
  }
8157
+ ],
8158
+ [
8159
+ "rovodev",
8160
+ {
8161
+ class: RovodevMcp,
8162
+ meta: {
8163
+ supportsProject: false,
8164
+ supportsGlobal: true,
8165
+ supportsEnabledTools: false,
8166
+ supportsDisabledTools: false
8167
+ }
8168
+ }
7945
8169
  ]
7946
8170
  ]);
7947
8171
  var allToolTargetKeys2 = [...toolMcpFactories.keys()];
@@ -8088,25 +8312,25 @@ var McpProcessor = class extends FeatureProcessor {
8088
8312
  };
8089
8313
 
8090
8314
  // src/features/rules/rules-processor.ts
8091
- import { basename as basename10, dirname as dirname3, join as join122, relative as relative5 } from "path";
8315
+ import { basename as basename10, dirname as dirname3, join as join126, relative as relative5 } from "path";
8092
8316
  import { encode } from "@toon-format/toon";
8093
- import { z as z59 } from "zod/mini";
8317
+ import { z as z61 } from "zod/mini";
8094
8318
 
8095
8319
  // src/constants/general.ts
8096
8320
  var SKILL_FILE_NAME = "SKILL.md";
8097
8321
 
8098
8322
  // src/features/skills/agentsmd-skill.ts
8099
- import { join as join61 } from "path";
8323
+ import { join as join62 } from "path";
8100
8324
 
8101
8325
  // src/features/skills/simulated-skill.ts
8102
- import { join as join60 } from "path";
8326
+ import { join as join61 } from "path";
8103
8327
  import { z as z24 } from "zod/mini";
8104
8328
 
8105
8329
  // src/features/skills/tool-skill.ts
8106
- import { join as join59 } from "path";
8330
+ import { join as join60 } from "path";
8107
8331
 
8108
8332
  // src/types/ai-dir.ts
8109
- import path2, { basename as basename3, join as join58, relative as relative4, resolve as resolve4 } from "path";
8333
+ import path2, { basename as basename3, join as join59, relative as relative4, resolve as resolve4 } from "path";
8110
8334
  var AiDir = class {
8111
8335
  /**
8112
8336
  * @example "."
@@ -8180,8 +8404,11 @@ var AiDir = class {
8180
8404
  getOtherFiles() {
8181
8405
  return this.otherFiles;
8182
8406
  }
8407
+ /**
8408
+ * Returns the relative path from CWD with POSIX separators for consistent cross-platform output.
8409
+ */
8183
8410
  getRelativePathFromCwd() {
8184
- return path2.join(this.relativeDirPath, this.dirName);
8411
+ return toPosixPath(path2.join(this.relativeDirPath, this.dirName));
8185
8412
  }
8186
8413
  getGlobal() {
8187
8414
  return this.global;
@@ -8200,8 +8427,8 @@ var AiDir = class {
8200
8427
  * @returns Array of files with their relative paths and buffers
8201
8428
  */
8202
8429
  static async collectOtherFiles(baseDir, relativeDirPath, dirName, excludeFileName) {
8203
- const dirPath = join58(baseDir, relativeDirPath, dirName);
8204
- const glob = join58(dirPath, "**", "*");
8430
+ const dirPath = join59(baseDir, relativeDirPath, dirName);
8431
+ const glob = join59(dirPath, "**", "*");
8205
8432
  const filePaths = await findFilesByGlobs(glob, { type: "file" });
8206
8433
  const filteredPaths = filePaths.filter((filePath) => basename3(filePath) !== excludeFileName);
8207
8434
  const files = await Promise.all(
@@ -8218,6 +8445,9 @@ var AiDir = class {
8218
8445
  };
8219
8446
 
8220
8447
  // src/features/skills/tool-skill.ts
8448
+ function toolSkillSearchRoots(paths) {
8449
+ return [paths.relativeDirPath, ...paths.alternativeSkillRoots ?? []];
8450
+ }
8221
8451
  var ToolSkill = class extends AiDir {
8222
8452
  /**
8223
8453
  * Get the settable paths for this tool's skill directories.
@@ -8299,8 +8529,8 @@ var ToolSkill = class extends AiDir {
8299
8529
  }) {
8300
8530
  const settablePaths = getSettablePaths({ global });
8301
8531
  const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
8302
- const skillDirPath = join59(baseDir, actualRelativeDirPath, dirName);
8303
- const skillFilePath = join59(skillDirPath, SKILL_FILE_NAME);
8532
+ const skillDirPath = join60(baseDir, actualRelativeDirPath, dirName);
8533
+ const skillFilePath = join60(skillDirPath, SKILL_FILE_NAME);
8304
8534
  if (!await fileExists(skillFilePath)) {
8305
8535
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
8306
8536
  }
@@ -8324,7 +8554,7 @@ var ToolSkill = class extends AiDir {
8324
8554
  }
8325
8555
  requireMainFileFrontmatter() {
8326
8556
  if (!this.mainFile?.frontmatter) {
8327
- throw new Error(`Frontmatter is not defined in ${join59(this.relativeDirPath, this.dirName)}`);
8557
+ throw new Error(`Frontmatter is not defined in ${join60(this.relativeDirPath, this.dirName)}`);
8328
8558
  }
8329
8559
  return this.mainFile.frontmatter;
8330
8560
  }
@@ -8364,7 +8594,7 @@ var SimulatedSkill = class extends ToolSkill {
8364
8594
  const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
8365
8595
  if (!result.success) {
8366
8596
  throw new Error(
8367
- `Invalid frontmatter in ${join60(relativeDirPath, dirName)}: ${formatError(result.error)}`
8597
+ `Invalid frontmatter in ${join61(relativeDirPath, dirName)}: ${formatError(result.error)}`
8368
8598
  );
8369
8599
  }
8370
8600
  }
@@ -8423,8 +8653,8 @@ var SimulatedSkill = class extends ToolSkill {
8423
8653
  }) {
8424
8654
  const settablePaths = this.getSettablePaths();
8425
8655
  const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
8426
- const skillDirPath = join60(baseDir, actualRelativeDirPath, dirName);
8427
- const skillFilePath = join60(skillDirPath, SKILL_FILE_NAME);
8656
+ const skillDirPath = join61(baseDir, actualRelativeDirPath, dirName);
8657
+ const skillFilePath = join61(skillDirPath, SKILL_FILE_NAME);
8428
8658
  if (!await fileExists(skillFilePath)) {
8429
8659
  throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
8430
8660
  }
@@ -8501,7 +8731,7 @@ var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
8501
8731
  throw new Error("AgentsmdSkill does not support global mode.");
8502
8732
  }
8503
8733
  return {
8504
- relativeDirPath: join61(".agents", "skills")
8734
+ relativeDirPath: join62(".agents", "skills")
8505
8735
  };
8506
8736
  }
8507
8737
  static async fromDir(params) {
@@ -8528,11 +8758,11 @@ var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
8528
8758
  };
8529
8759
 
8530
8760
  // src/features/skills/factorydroid-skill.ts
8531
- import { join as join62 } from "path";
8761
+ import { join as join63 } from "path";
8532
8762
  var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
8533
8763
  static getSettablePaths(_options) {
8534
8764
  return {
8535
- relativeDirPath: join62(".factory", "skills")
8765
+ relativeDirPath: join63(".factory", "skills")
8536
8766
  };
8537
8767
  }
8538
8768
  static async fromDir(params) {
@@ -8558,41 +8788,349 @@ var FactorydroidSkill = class _FactorydroidSkill extends SimulatedSkill {
8558
8788
  }
8559
8789
  };
8560
8790
 
8561
- // src/features/skills/skills-processor.ts
8562
- import { basename as basename5, join as join81 } from "path";
8563
- import { z as z41 } from "zod/mini";
8791
+ // src/features/skills/rovodev-skill.ts
8792
+ import { join as join65 } from "path";
8793
+ import { z as z26 } from "zod/mini";
8564
8794
 
8565
- // src/types/dir-feature-processor.ts
8566
- import { join as join63 } from "path";
8567
- var DirFeatureProcessor = class {
8568
- baseDir;
8569
- dryRun;
8570
- avoidBlockScalars;
8571
- logger;
8795
+ // src/features/skills/rulesync-skill.ts
8796
+ import { join as join64 } from "path";
8797
+ import { z as z25 } from "zod/mini";
8798
+ var RulesyncSkillFrontmatterSchemaInternal = z25.looseObject({
8799
+ name: z25.string(),
8800
+ description: z25.string(),
8801
+ targets: z25._default(RulesyncTargetsSchema, ["*"]),
8802
+ claudecode: z25.optional(
8803
+ z25.looseObject({
8804
+ "allowed-tools": z25.optional(z25.array(z25.string())),
8805
+ model: z25.optional(z25.string()),
8806
+ "disable-model-invocation": z25.optional(z25.boolean())
8807
+ })
8808
+ ),
8809
+ codexcli: z25.optional(
8810
+ z25.looseObject({
8811
+ "short-description": z25.optional(z25.string())
8812
+ })
8813
+ ),
8814
+ opencode: z25.optional(
8815
+ z25.looseObject({
8816
+ "allowed-tools": z25.optional(z25.array(z25.string()))
8817
+ })
8818
+ ),
8819
+ deepagents: z25.optional(
8820
+ z25.looseObject({
8821
+ "allowed-tools": z25.optional(z25.array(z25.string()))
8822
+ })
8823
+ ),
8824
+ copilot: z25.optional(
8825
+ z25.looseObject({
8826
+ license: z25.optional(z25.string())
8827
+ })
8828
+ ),
8829
+ cline: z25.optional(z25.looseObject({})),
8830
+ roo: z25.optional(z25.looseObject({}))
8831
+ });
8832
+ var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
8833
+ var RulesyncSkill = class _RulesyncSkill extends AiDir {
8572
8834
  constructor({
8573
8835
  baseDir = process.cwd(),
8574
- dryRun = false,
8575
- avoidBlockScalars = false,
8576
- logger
8836
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
8837
+ dirName,
8838
+ frontmatter,
8839
+ body,
8840
+ otherFiles = [],
8841
+ validate = true,
8842
+ global = false
8577
8843
  }) {
8578
- this.baseDir = baseDir;
8579
- this.dryRun = dryRun;
8580
- this.avoidBlockScalars = avoidBlockScalars;
8581
- this.logger = logger;
8844
+ super({
8845
+ baseDir,
8846
+ relativeDirPath,
8847
+ dirName,
8848
+ mainFile: {
8849
+ name: SKILL_FILE_NAME,
8850
+ body,
8851
+ frontmatter: { ...frontmatter }
8852
+ },
8853
+ otherFiles,
8854
+ global
8855
+ });
8856
+ if (validate) {
8857
+ const result = this.validate();
8858
+ if (!result.success) {
8859
+ throw result.error;
8860
+ }
8861
+ }
8582
8862
  }
8583
- /**
8584
- * Return tool targets that this feature supports.
8585
- */
8586
- static getToolTargets(_params = {}) {
8587
- throw new Error("Not implemented");
8863
+ static getSettablePaths() {
8864
+ return {
8865
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
8866
+ };
8588
8867
  }
8589
- /**
8590
- * Once converted to rulesync/tool dirs, write them to the filesystem.
8591
- * Returns the number of directories written.
8592
- *
8593
- * Note: This method uses directory-level change detection. If any file within
8594
- * a directory has changed, ALL files in that directory are rewritten. This is
8595
- * an intentional design decision to ensure consistency within directory units.
8868
+ getFrontmatter() {
8869
+ if (!this.mainFile?.frontmatter) {
8870
+ throw new Error(`Frontmatter is not defined in ${join64(this.relativeDirPath, this.dirName)}`);
8871
+ }
8872
+ const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
8873
+ return result;
8874
+ }
8875
+ getBody() {
8876
+ return this.mainFile?.body ?? "";
8877
+ }
8878
+ validate() {
8879
+ const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
8880
+ if (!result.success) {
8881
+ return {
8882
+ success: false,
8883
+ error: new Error(
8884
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
8885
+ )
8886
+ };
8887
+ }
8888
+ return { success: true, error: null };
8889
+ }
8890
+ static async fromDir({
8891
+ baseDir = process.cwd(),
8892
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
8893
+ dirName,
8894
+ global = false
8895
+ }) {
8896
+ const skillDirPath = join64(baseDir, relativeDirPath, dirName);
8897
+ const skillFilePath = join64(skillDirPath, SKILL_FILE_NAME);
8898
+ if (!await fileExists(skillFilePath)) {
8899
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
8900
+ }
8901
+ const fileContent = await readFileContent(skillFilePath);
8902
+ const { frontmatter, body: content } = parseFrontmatter(fileContent, skillFilePath);
8903
+ const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
8904
+ if (!result.success) {
8905
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
8906
+ }
8907
+ const otherFiles = await this.collectOtherFiles(
8908
+ baseDir,
8909
+ relativeDirPath,
8910
+ dirName,
8911
+ SKILL_FILE_NAME
8912
+ );
8913
+ return new _RulesyncSkill({
8914
+ baseDir,
8915
+ relativeDirPath,
8916
+ dirName,
8917
+ frontmatter: result.data,
8918
+ body: content.trim(),
8919
+ otherFiles,
8920
+ validate: true,
8921
+ global
8922
+ });
8923
+ }
8924
+ };
8925
+
8926
+ // src/features/skills/rovodev-skill.ts
8927
+ var RovodevSkillFrontmatterSchema = z26.looseObject({
8928
+ name: z26.string(),
8929
+ description: z26.string()
8930
+ });
8931
+ var RovodevSkill = class _RovodevSkill extends ToolSkill {
8932
+ constructor({
8933
+ baseDir = process.cwd(),
8934
+ relativeDirPath = join65(".rovodev", "skills"),
8935
+ dirName,
8936
+ frontmatter,
8937
+ body,
8938
+ otherFiles = [],
8939
+ validate = true,
8940
+ global = false
8941
+ }) {
8942
+ super({
8943
+ baseDir,
8944
+ relativeDirPath,
8945
+ dirName,
8946
+ mainFile: {
8947
+ name: SKILL_FILE_NAME,
8948
+ body,
8949
+ frontmatter: { ...frontmatter }
8950
+ },
8951
+ otherFiles,
8952
+ global
8953
+ });
8954
+ if (validate) {
8955
+ const result = this.validate();
8956
+ if (!result.success) {
8957
+ throw result.error;
8958
+ }
8959
+ }
8960
+ }
8961
+ static getSettablePaths(_options) {
8962
+ return {
8963
+ relativeDirPath: join65(".rovodev", "skills"),
8964
+ alternativeSkillRoots: [join65(".agents", "skills")]
8965
+ };
8966
+ }
8967
+ getFrontmatter() {
8968
+ const result = RovodevSkillFrontmatterSchema.parse(this.requireMainFileFrontmatter());
8969
+ return result;
8970
+ }
8971
+ getBody() {
8972
+ return this.mainFile?.body ?? "";
8973
+ }
8974
+ validate() {
8975
+ if (!this.mainFile) {
8976
+ return {
8977
+ success: false,
8978
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
8979
+ };
8980
+ }
8981
+ const result = RovodevSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
8982
+ if (!result.success) {
8983
+ return {
8984
+ success: false,
8985
+ error: new Error(
8986
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
8987
+ )
8988
+ };
8989
+ }
8990
+ if (result.data.name !== this.getDirName()) {
8991
+ return {
8992
+ success: false,
8993
+ error: new Error(
8994
+ `${this.getDirPath()}: frontmatter name (${result.data.name}) must match directory name (${this.getDirName()})`
8995
+ )
8996
+ };
8997
+ }
8998
+ return { success: true, error: null };
8999
+ }
9000
+ toRulesyncSkill() {
9001
+ const frontmatter = this.getFrontmatter();
9002
+ const rulesyncFrontmatter = {
9003
+ name: frontmatter.name,
9004
+ description: frontmatter.description,
9005
+ targets: ["*"]
9006
+ };
9007
+ return new RulesyncSkill({
9008
+ baseDir: this.baseDir,
9009
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
9010
+ dirName: this.getDirName(),
9011
+ frontmatter: rulesyncFrontmatter,
9012
+ body: this.getBody(),
9013
+ otherFiles: this.getOtherFiles(),
9014
+ validate: true,
9015
+ global: this.global
9016
+ });
9017
+ }
9018
+ static fromRulesyncSkill({
9019
+ baseDir = process.cwd(),
9020
+ rulesyncSkill,
9021
+ validate = true,
9022
+ global = false
9023
+ }) {
9024
+ const settablePaths = _RovodevSkill.getSettablePaths({ global });
9025
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
9026
+ const rovodevFrontmatter = {
9027
+ name: rulesyncFrontmatter.name,
9028
+ description: rulesyncFrontmatter.description
9029
+ };
9030
+ return new _RovodevSkill({
9031
+ baseDir,
9032
+ relativeDirPath: settablePaths.relativeDirPath,
9033
+ dirName: rovodevFrontmatter.name,
9034
+ frontmatter: rovodevFrontmatter,
9035
+ body: rulesyncSkill.getBody(),
9036
+ otherFiles: rulesyncSkill.getOtherFiles(),
9037
+ validate,
9038
+ global
9039
+ });
9040
+ }
9041
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
9042
+ const targets = rulesyncSkill.getFrontmatter().targets;
9043
+ return targets.includes("*") || targets.includes("rovodev");
9044
+ }
9045
+ static async fromDir(params) {
9046
+ const loaded = await this.loadSkillDirContent({
9047
+ ...params,
9048
+ getSettablePaths: _RovodevSkill.getSettablePaths
9049
+ });
9050
+ const result = RovodevSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9051
+ if (!result.success) {
9052
+ const skillDirPath = join65(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9053
+ throw new Error(
9054
+ `Invalid frontmatter in ${join65(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9055
+ );
9056
+ }
9057
+ if (result.data.name !== loaded.dirName) {
9058
+ const skillFilePath = join65(
9059
+ loaded.baseDir,
9060
+ loaded.relativeDirPath,
9061
+ loaded.dirName,
9062
+ SKILL_FILE_NAME
9063
+ );
9064
+ throw new Error(
9065
+ `Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`
9066
+ );
9067
+ }
9068
+ return new _RovodevSkill({
9069
+ baseDir: loaded.baseDir,
9070
+ relativeDirPath: loaded.relativeDirPath,
9071
+ dirName: loaded.dirName,
9072
+ frontmatter: result.data,
9073
+ body: loaded.body,
9074
+ otherFiles: loaded.otherFiles,
9075
+ validate: true,
9076
+ global: loaded.global
9077
+ });
9078
+ }
9079
+ static forDeletion({
9080
+ baseDir = process.cwd(),
9081
+ relativeDirPath,
9082
+ dirName,
9083
+ global = false
9084
+ }) {
9085
+ const settablePaths = _RovodevSkill.getSettablePaths({ global });
9086
+ return new _RovodevSkill({
9087
+ baseDir,
9088
+ relativeDirPath: relativeDirPath ?? settablePaths.relativeDirPath,
9089
+ dirName,
9090
+ frontmatter: { name: "", description: "" },
9091
+ body: "",
9092
+ otherFiles: [],
9093
+ validate: false,
9094
+ global
9095
+ });
9096
+ }
9097
+ };
9098
+
9099
+ // src/features/skills/skills-processor.ts
9100
+ import { basename as basename5, join as join83 } from "path";
9101
+ import { z as z42 } from "zod/mini";
9102
+
9103
+ // src/types/dir-feature-processor.ts
9104
+ import { join as join66 } from "path";
9105
+ var DirFeatureProcessor = class {
9106
+ baseDir;
9107
+ dryRun;
9108
+ avoidBlockScalars;
9109
+ logger;
9110
+ constructor({
9111
+ baseDir = process.cwd(),
9112
+ dryRun = false,
9113
+ avoidBlockScalars = false,
9114
+ logger
9115
+ }) {
9116
+ this.baseDir = baseDir;
9117
+ this.dryRun = dryRun;
9118
+ this.avoidBlockScalars = avoidBlockScalars;
9119
+ this.logger = logger;
9120
+ }
9121
+ /**
9122
+ * Return tool targets that this feature supports.
9123
+ */
9124
+ static getToolTargets(_params = {}) {
9125
+ throw new Error("Not implemented");
9126
+ }
9127
+ /**
9128
+ * Once converted to rulesync/tool dirs, write them to the filesystem.
9129
+ * Returns the number of directories written.
9130
+ *
9131
+ * Note: This method uses directory-level change detection. If any file within
9132
+ * a directory has changed, ALL files in that directory are rewritten. This is
9133
+ * an intentional design decision to ensure consistency within directory units.
8596
9134
  */
8597
9135
  async writeAiDirs(aiDirs) {
8598
9136
  let changedCount = 0;
@@ -8603,13 +9141,17 @@ var DirFeatureProcessor = class {
8603
9141
  const mainFile = aiDir.getMainFile();
8604
9142
  let mainFileContent;
8605
9143
  if (mainFile) {
8606
- const mainFilePath = join63(dirPath, mainFile.name);
9144
+ const mainFilePath = join66(dirPath, mainFile.name);
8607
9145
  const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter, {
8608
9146
  avoidBlockScalars: this.avoidBlockScalars
8609
9147
  });
8610
9148
  mainFileContent = addTrailingNewline(content);
8611
9149
  const existingContent = await readFileContentOrNull(mainFilePath);
8612
- if (existingContent !== mainFileContent) {
9150
+ if (!fileContentsEquivalent({
9151
+ filePath: mainFilePath,
9152
+ expected: mainFileContent,
9153
+ existing: existingContent
9154
+ })) {
8613
9155
  dirHasChanges = true;
8614
9156
  }
8615
9157
  }
@@ -8619,9 +9161,13 @@ var DirFeatureProcessor = class {
8619
9161
  const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
8620
9162
  otherFileContents.push(contentWithNewline);
8621
9163
  if (!dirHasChanges) {
8622
- const filePath = join63(dirPath, file.relativeFilePathToDirPath);
9164
+ const filePath = join66(dirPath, file.relativeFilePathToDirPath);
8623
9165
  const existingContent = await readFileContentOrNull(filePath);
8624
- if (existingContent !== contentWithNewline) {
9166
+ if (!fileContentsEquivalent({
9167
+ filePath,
9168
+ expected: contentWithNewline,
9169
+ existing: existingContent
9170
+ })) {
8625
9171
  dirHasChanges = true;
8626
9172
  }
8627
9173
  }
@@ -8633,206 +9179,73 @@ var DirFeatureProcessor = class {
8633
9179
  if (this.dryRun) {
8634
9180
  this.logger.info(`[DRY RUN] Would create directory: ${dirPath}`);
8635
9181
  if (mainFile) {
8636
- this.logger.info(`[DRY RUN] Would write: ${join63(dirPath, mainFile.name)}`);
8637
- changedPaths.push(join63(relativeDir, mainFile.name));
9182
+ this.logger.info(`[DRY RUN] Would write: ${join66(dirPath, mainFile.name)}`);
9183
+ changedPaths.push(join66(relativeDir, mainFile.name));
8638
9184
  }
8639
9185
  for (const file of otherFiles) {
8640
9186
  this.logger.info(
8641
- `[DRY RUN] Would write: ${join63(dirPath, file.relativeFilePathToDirPath)}`
9187
+ `[DRY RUN] Would write: ${join66(dirPath, file.relativeFilePathToDirPath)}`
8642
9188
  );
8643
- changedPaths.push(join63(relativeDir, file.relativeFilePathToDirPath));
9189
+ changedPaths.push(join66(relativeDir, file.relativeFilePathToDirPath));
8644
9190
  }
8645
9191
  } else {
8646
9192
  await ensureDir(dirPath);
8647
9193
  if (mainFile && mainFileContent) {
8648
- const mainFilePath = join63(dirPath, mainFile.name);
9194
+ const mainFilePath = join66(dirPath, mainFile.name);
8649
9195
  await writeFileContent(mainFilePath, mainFileContent);
8650
- changedPaths.push(join63(relativeDir, mainFile.name));
9196
+ changedPaths.push(join66(relativeDir, mainFile.name));
8651
9197
  }
8652
9198
  for (const [i, file] of otherFiles.entries()) {
8653
- const filePath = join63(dirPath, file.relativeFilePathToDirPath);
9199
+ const filePath = join66(dirPath, file.relativeFilePathToDirPath);
8654
9200
  const content = otherFileContents[i];
8655
9201
  if (content === void 0) {
8656
9202
  throw new Error(
8657
9203
  `Internal error: content for file ${file.relativeFilePathToDirPath} is undefined. This indicates a synchronization issue between otherFiles and otherFileContents arrays.`
8658
9204
  );
8659
- }
8660
- await writeFileContent(filePath, content);
8661
- changedPaths.push(join63(relativeDir, file.relativeFilePathToDirPath));
8662
- }
8663
- }
8664
- changedCount++;
8665
- }
8666
- return { count: changedCount, paths: changedPaths };
8667
- }
8668
- async removeAiDirs(aiDirs) {
8669
- for (const aiDir of aiDirs) {
8670
- await removeDirectory(aiDir.getDirPath());
8671
- }
8672
- }
8673
- /**
8674
- * Remove orphan directories that exist in the tool directory but not in the generated directories.
8675
- * This only deletes directories that are no longer in the rulesync source, not directories that will be overwritten.
8676
- */
8677
- async removeOrphanAiDirs(existingDirs, generatedDirs) {
8678
- const generatedPaths = new Set(generatedDirs.map((d) => d.getDirPath()));
8679
- const orphanDirs = existingDirs.filter((d) => !generatedPaths.has(d.getDirPath()));
8680
- for (const aiDir of orphanDirs) {
8681
- const dirPath = aiDir.getDirPath();
8682
- if (this.dryRun) {
8683
- this.logger.info(`[DRY RUN] Would delete directory: ${dirPath}`);
8684
- } else {
8685
- await removeDirectory(dirPath);
8686
- }
8687
- }
8688
- return orphanDirs.length;
8689
- }
8690
- };
8691
-
8692
- // src/features/skills/agentsskills-skill.ts
8693
- import { join as join65 } from "path";
8694
- import { z as z26 } from "zod/mini";
8695
-
8696
- // src/features/skills/rulesync-skill.ts
8697
- import { join as join64 } from "path";
8698
- import { z as z25 } from "zod/mini";
8699
- var RulesyncSkillFrontmatterSchemaInternal = z25.looseObject({
8700
- name: z25.string(),
8701
- description: z25.string(),
8702
- targets: z25._default(RulesyncTargetsSchema, ["*"]),
8703
- claudecode: z25.optional(
8704
- z25.looseObject({
8705
- "allowed-tools": z25.optional(z25.array(z25.string())),
8706
- model: z25.optional(z25.string()),
8707
- "disable-model-invocation": z25.optional(z25.boolean())
8708
- })
8709
- ),
8710
- codexcli: z25.optional(
8711
- z25.looseObject({
8712
- "short-description": z25.optional(z25.string())
8713
- })
8714
- ),
8715
- opencode: z25.optional(
8716
- z25.looseObject({
8717
- "allowed-tools": z25.optional(z25.array(z25.string()))
8718
- })
8719
- ),
8720
- deepagents: z25.optional(
8721
- z25.looseObject({
8722
- "allowed-tools": z25.optional(z25.array(z25.string()))
8723
- })
8724
- ),
8725
- copilot: z25.optional(
8726
- z25.looseObject({
8727
- license: z25.optional(z25.string())
8728
- })
8729
- ),
8730
- cline: z25.optional(z25.looseObject({})),
8731
- roo: z25.optional(z25.looseObject({}))
8732
- });
8733
- var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
8734
- var RulesyncSkill = class _RulesyncSkill extends AiDir {
8735
- constructor({
8736
- baseDir = process.cwd(),
8737
- relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
8738
- dirName,
8739
- frontmatter,
8740
- body,
8741
- otherFiles = [],
8742
- validate = true,
8743
- global = false
8744
- }) {
8745
- super({
8746
- baseDir,
8747
- relativeDirPath,
8748
- dirName,
8749
- mainFile: {
8750
- name: SKILL_FILE_NAME,
8751
- body,
8752
- frontmatter: { ...frontmatter }
8753
- },
8754
- otherFiles,
8755
- global
8756
- });
8757
- if (validate) {
8758
- const result = this.validate();
8759
- if (!result.success) {
8760
- throw result.error;
8761
- }
8762
- }
8763
- }
8764
- static getSettablePaths() {
8765
- return {
8766
- relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
8767
- };
8768
- }
8769
- getFrontmatter() {
8770
- if (!this.mainFile?.frontmatter) {
8771
- throw new Error(`Frontmatter is not defined in ${join64(this.relativeDirPath, this.dirName)}`);
9205
+ }
9206
+ await writeFileContent(filePath, content);
9207
+ changedPaths.push(join66(relativeDir, file.relativeFilePathToDirPath));
9208
+ }
9209
+ }
9210
+ changedCount++;
8772
9211
  }
8773
- const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
8774
- return result;
8775
- }
8776
- getBody() {
8777
- return this.mainFile?.body ?? "";
9212
+ return { count: changedCount, paths: changedPaths };
8778
9213
  }
8779
- validate() {
8780
- const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
8781
- if (!result.success) {
8782
- return {
8783
- success: false,
8784
- error: new Error(
8785
- `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
8786
- )
8787
- };
9214
+ async removeAiDirs(aiDirs) {
9215
+ for (const aiDir of aiDirs) {
9216
+ await removeDirectory(aiDir.getDirPath());
8788
9217
  }
8789
- return { success: true, error: null };
8790
9218
  }
8791
- static async fromDir({
8792
- baseDir = process.cwd(),
8793
- relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
8794
- dirName,
8795
- global = false
8796
- }) {
8797
- const skillDirPath = join64(baseDir, relativeDirPath, dirName);
8798
- const skillFilePath = join64(skillDirPath, SKILL_FILE_NAME);
8799
- if (!await fileExists(skillFilePath)) {
8800
- throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
8801
- }
8802
- const fileContent = await readFileContent(skillFilePath);
8803
- const { frontmatter, body: content } = parseFrontmatter(fileContent, skillFilePath);
8804
- const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
8805
- if (!result.success) {
8806
- throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
9219
+ /**
9220
+ * Remove orphan directories that exist in the tool directory but not in the generated directories.
9221
+ * This only deletes directories that are no longer in the rulesync source, not directories that will be overwritten.
9222
+ */
9223
+ async removeOrphanAiDirs(existingDirs, generatedDirs) {
9224
+ const generatedPaths = new Set(generatedDirs.map((d) => d.getDirPath()));
9225
+ const orphanDirs = existingDirs.filter((d) => !generatedPaths.has(d.getDirPath()));
9226
+ for (const aiDir of orphanDirs) {
9227
+ const dirPath = aiDir.getDirPath();
9228
+ if (this.dryRun) {
9229
+ this.logger.info(`[DRY RUN] Would delete directory: ${dirPath}`);
9230
+ } else {
9231
+ await removeDirectory(dirPath);
9232
+ }
8807
9233
  }
8808
- const otherFiles = await this.collectOtherFiles(
8809
- baseDir,
8810
- relativeDirPath,
8811
- dirName,
8812
- SKILL_FILE_NAME
8813
- );
8814
- return new _RulesyncSkill({
8815
- baseDir,
8816
- relativeDirPath,
8817
- dirName,
8818
- frontmatter: result.data,
8819
- body: content.trim(),
8820
- otherFiles,
8821
- validate: true,
8822
- global
8823
- });
9234
+ return orphanDirs.length;
8824
9235
  }
8825
9236
  };
8826
9237
 
8827
9238
  // src/features/skills/agentsskills-skill.ts
8828
- var AgentsSkillsSkillFrontmatterSchema = z26.looseObject({
8829
- name: z26.string(),
8830
- description: z26.string()
9239
+ import { join as join67 } from "path";
9240
+ import { z as z27 } from "zod/mini";
9241
+ var AgentsSkillsSkillFrontmatterSchema = z27.looseObject({
9242
+ name: z27.string(),
9243
+ description: z27.string()
8831
9244
  });
8832
9245
  var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
8833
9246
  constructor({
8834
9247
  baseDir = process.cwd(),
8835
- relativeDirPath = join65(".agents", "skills"),
9248
+ relativeDirPath = join67(".agents", "skills"),
8836
9249
  dirName,
8837
9250
  frontmatter,
8838
9251
  body,
@@ -8864,7 +9277,7 @@ var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
8864
9277
  throw new Error("AgentsSkillsSkill does not support global mode.");
8865
9278
  }
8866
9279
  return {
8867
- relativeDirPath: join65(".agents", "skills")
9280
+ relativeDirPath: join67(".agents", "skills")
8868
9281
  };
8869
9282
  }
8870
9283
  getFrontmatter() {
@@ -8944,9 +9357,9 @@ var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
8944
9357
  });
8945
9358
  const result = AgentsSkillsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
8946
9359
  if (!result.success) {
8947
- const skillDirPath = join65(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9360
+ const skillDirPath = join67(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
8948
9361
  throw new Error(
8949
- `Invalid frontmatter in ${join65(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9362
+ `Invalid frontmatter in ${join67(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
8950
9363
  );
8951
9364
  }
8952
9365
  return new _AgentsSkillsSkill({
@@ -8981,16 +9394,16 @@ var AgentsSkillsSkill = class _AgentsSkillsSkill extends ToolSkill {
8981
9394
  };
8982
9395
 
8983
9396
  // src/features/skills/antigravity-skill.ts
8984
- import { join as join66 } from "path";
8985
- import { z as z27 } from "zod/mini";
8986
- var AntigravitySkillFrontmatterSchema = z27.looseObject({
8987
- name: z27.string(),
8988
- description: z27.string()
9397
+ import { join as join68 } from "path";
9398
+ import { z as z28 } from "zod/mini";
9399
+ var AntigravitySkillFrontmatterSchema = z28.looseObject({
9400
+ name: z28.string(),
9401
+ description: z28.string()
8989
9402
  });
8990
9403
  var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
8991
9404
  constructor({
8992
9405
  baseDir = process.cwd(),
8993
- relativeDirPath = join66(".agent", "skills"),
9406
+ relativeDirPath = join68(".agent", "skills"),
8994
9407
  dirName,
8995
9408
  frontmatter,
8996
9409
  body,
@@ -9022,11 +9435,11 @@ var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
9022
9435
  } = {}) {
9023
9436
  if (global) {
9024
9437
  return {
9025
- relativeDirPath: join66(".gemini", "antigravity", "skills")
9438
+ relativeDirPath: join68(".gemini", "antigravity", "skills")
9026
9439
  };
9027
9440
  }
9028
9441
  return {
9029
- relativeDirPath: join66(".agent", "skills")
9442
+ relativeDirPath: join68(".agent", "skills")
9030
9443
  };
9031
9444
  }
9032
9445
  getFrontmatter() {
@@ -9106,9 +9519,9 @@ var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
9106
9519
  });
9107
9520
  const result = AntigravitySkillFrontmatterSchema.safeParse(loaded.frontmatter);
9108
9521
  if (!result.success) {
9109
- const skillDirPath = join66(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9522
+ const skillDirPath = join68(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9110
9523
  throw new Error(
9111
- `Invalid frontmatter in ${join66(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9524
+ `Invalid frontmatter in ${join68(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9112
9525
  );
9113
9526
  }
9114
9527
  return new _AntigravitySkill({
@@ -9142,19 +9555,19 @@ var AntigravitySkill = class _AntigravitySkill extends ToolSkill {
9142
9555
  };
9143
9556
 
9144
9557
  // src/features/skills/claudecode-skill.ts
9145
- import { join as join67 } from "path";
9146
- import { z as z28 } from "zod/mini";
9147
- var ClaudecodeSkillFrontmatterSchema = z28.looseObject({
9148
- name: z28.string(),
9149
- description: z28.string(),
9150
- "allowed-tools": z28.optional(z28.array(z28.string())),
9151
- model: z28.optional(z28.string()),
9152
- "disable-model-invocation": z28.optional(z28.boolean())
9558
+ import { join as join69 } from "path";
9559
+ import { z as z29 } from "zod/mini";
9560
+ var ClaudecodeSkillFrontmatterSchema = z29.looseObject({
9561
+ name: z29.string(),
9562
+ description: z29.string(),
9563
+ "allowed-tools": z29.optional(z29.array(z29.string())),
9564
+ model: z29.optional(z29.string()),
9565
+ "disable-model-invocation": z29.optional(z29.boolean())
9153
9566
  });
9154
9567
  var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
9155
9568
  constructor({
9156
9569
  baseDir = process.cwd(),
9157
- relativeDirPath = join67(".claude", "skills"),
9570
+ relativeDirPath = join69(".claude", "skills"),
9158
9571
  dirName,
9159
9572
  frontmatter,
9160
9573
  body,
@@ -9185,7 +9598,7 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
9185
9598
  global: _global = false
9186
9599
  } = {}) {
9187
9600
  return {
9188
- relativeDirPath: join67(".claude", "skills")
9601
+ relativeDirPath: join69(".claude", "skills")
9189
9602
  };
9190
9603
  }
9191
9604
  getFrontmatter() {
@@ -9282,9 +9695,9 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
9282
9695
  });
9283
9696
  const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9284
9697
  if (!result.success) {
9285
- const skillDirPath = join67(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9698
+ const skillDirPath = join69(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9286
9699
  throw new Error(
9287
- `Invalid frontmatter in ${join67(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9700
+ `Invalid frontmatter in ${join69(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9288
9701
  );
9289
9702
  }
9290
9703
  return new _ClaudecodeSkill({
@@ -9318,16 +9731,16 @@ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
9318
9731
  };
9319
9732
 
9320
9733
  // src/features/skills/cline-skill.ts
9321
- import { join as join68 } from "path";
9322
- import { z as z29 } from "zod/mini";
9323
- var ClineSkillFrontmatterSchema = z29.looseObject({
9324
- name: z29.string(),
9325
- description: z29.string()
9734
+ import { join as join70 } from "path";
9735
+ import { z as z30 } from "zod/mini";
9736
+ var ClineSkillFrontmatterSchema = z30.looseObject({
9737
+ name: z30.string(),
9738
+ description: z30.string()
9326
9739
  });
9327
9740
  var ClineSkill = class _ClineSkill extends ToolSkill {
9328
9741
  constructor({
9329
9742
  baseDir = process.cwd(),
9330
- relativeDirPath = join68(".cline", "skills"),
9743
+ relativeDirPath = join70(".cline", "skills"),
9331
9744
  dirName,
9332
9745
  frontmatter,
9333
9746
  body,
@@ -9356,7 +9769,7 @@ var ClineSkill = class _ClineSkill extends ToolSkill {
9356
9769
  }
9357
9770
  static getSettablePaths(_options = {}) {
9358
9771
  return {
9359
- relativeDirPath: join68(".cline", "skills")
9772
+ relativeDirPath: join70(".cline", "skills")
9360
9773
  };
9361
9774
  }
9362
9775
  getFrontmatter() {
@@ -9444,13 +9857,13 @@ var ClineSkill = class _ClineSkill extends ToolSkill {
9444
9857
  });
9445
9858
  const result = ClineSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9446
9859
  if (!result.success) {
9447
- const skillDirPath = join68(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9860
+ const skillDirPath = join70(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9448
9861
  throw new Error(
9449
- `Invalid frontmatter in ${join68(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9862
+ `Invalid frontmatter in ${join70(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9450
9863
  );
9451
9864
  }
9452
9865
  if (result.data.name !== loaded.dirName) {
9453
- const skillFilePath = join68(
9866
+ const skillFilePath = join70(
9454
9867
  loaded.baseDir,
9455
9868
  loaded.relativeDirPath,
9456
9869
  loaded.dirName,
@@ -9491,21 +9904,21 @@ var ClineSkill = class _ClineSkill extends ToolSkill {
9491
9904
  };
9492
9905
 
9493
9906
  // src/features/skills/codexcli-skill.ts
9494
- import { join as join69 } from "path";
9495
- import { z as z30 } from "zod/mini";
9496
- var CodexCliSkillFrontmatterSchema = z30.looseObject({
9497
- name: z30.string(),
9498
- description: z30.string(),
9499
- metadata: z30.optional(
9500
- z30.looseObject({
9501
- "short-description": z30.optional(z30.string())
9907
+ import { join as join71 } from "path";
9908
+ import { z as z31 } from "zod/mini";
9909
+ var CodexCliSkillFrontmatterSchema = z31.looseObject({
9910
+ name: z31.string(),
9911
+ description: z31.string(),
9912
+ metadata: z31.optional(
9913
+ z31.looseObject({
9914
+ "short-description": z31.optional(z31.string())
9502
9915
  })
9503
9916
  )
9504
9917
  });
9505
9918
  var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
9506
9919
  constructor({
9507
9920
  baseDir = process.cwd(),
9508
- relativeDirPath = join69(".codex", "skills"),
9921
+ relativeDirPath = join71(".codex", "skills"),
9509
9922
  dirName,
9510
9923
  frontmatter,
9511
9924
  body,
@@ -9536,7 +9949,7 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
9536
9949
  global: _global = false
9537
9950
  } = {}) {
9538
9951
  return {
9539
- relativeDirPath: join69(".codex", "skills")
9952
+ relativeDirPath: join71(".codex", "skills")
9540
9953
  };
9541
9954
  }
9542
9955
  getFrontmatter() {
@@ -9626,9 +10039,9 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
9626
10039
  });
9627
10040
  const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9628
10041
  if (!result.success) {
9629
- const skillDirPath = join69(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10042
+ const skillDirPath = join71(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9630
10043
  throw new Error(
9631
- `Invalid frontmatter in ${join69(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10044
+ `Invalid frontmatter in ${join71(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9632
10045
  );
9633
10046
  }
9634
10047
  return new _CodexCliSkill({
@@ -9662,17 +10075,17 @@ var CodexCliSkill = class _CodexCliSkill extends ToolSkill {
9662
10075
  };
9663
10076
 
9664
10077
  // src/features/skills/copilot-skill.ts
9665
- import { join as join70 } from "path";
9666
- import { z as z31 } from "zod/mini";
9667
- var CopilotSkillFrontmatterSchema = z31.looseObject({
9668
- name: z31.string(),
9669
- description: z31.string(),
9670
- license: z31.optional(z31.string())
10078
+ import { join as join72 } from "path";
10079
+ import { z as z32 } from "zod/mini";
10080
+ var CopilotSkillFrontmatterSchema = z32.looseObject({
10081
+ name: z32.string(),
10082
+ description: z32.string(),
10083
+ license: z32.optional(z32.string())
9671
10084
  });
9672
10085
  var CopilotSkill = class _CopilotSkill extends ToolSkill {
9673
10086
  constructor({
9674
10087
  baseDir = process.cwd(),
9675
- relativeDirPath = join70(".github", "skills"),
10088
+ relativeDirPath = join72(".github", "skills"),
9676
10089
  dirName,
9677
10090
  frontmatter,
9678
10091
  body,
@@ -9704,7 +10117,7 @@ var CopilotSkill = class _CopilotSkill extends ToolSkill {
9704
10117
  throw new Error("CopilotSkill does not support global mode.");
9705
10118
  }
9706
10119
  return {
9707
- relativeDirPath: join70(".github", "skills")
10120
+ relativeDirPath: join72(".github", "skills")
9708
10121
  };
9709
10122
  }
9710
10123
  getFrontmatter() {
@@ -9790,9 +10203,9 @@ var CopilotSkill = class _CopilotSkill extends ToolSkill {
9790
10203
  });
9791
10204
  const result = CopilotSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9792
10205
  if (!result.success) {
9793
- const skillDirPath = join70(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10206
+ const skillDirPath = join72(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9794
10207
  throw new Error(
9795
- `Invalid frontmatter in ${join70(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10208
+ `Invalid frontmatter in ${join72(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9796
10209
  );
9797
10210
  }
9798
10211
  return new _CopilotSkill({
@@ -9827,16 +10240,16 @@ var CopilotSkill = class _CopilotSkill extends ToolSkill {
9827
10240
  };
9828
10241
 
9829
10242
  // src/features/skills/cursor-skill.ts
9830
- import { join as join71 } from "path";
9831
- import { z as z32 } from "zod/mini";
9832
- var CursorSkillFrontmatterSchema = z32.looseObject({
9833
- name: z32.string(),
9834
- description: z32.string()
10243
+ import { join as join73 } from "path";
10244
+ import { z as z33 } from "zod/mini";
10245
+ var CursorSkillFrontmatterSchema = z33.looseObject({
10246
+ name: z33.string(),
10247
+ description: z33.string()
9835
10248
  });
9836
10249
  var CursorSkill = class _CursorSkill extends ToolSkill {
9837
10250
  constructor({
9838
10251
  baseDir = process.cwd(),
9839
- relativeDirPath = join71(".cursor", "skills"),
10252
+ relativeDirPath = join73(".cursor", "skills"),
9840
10253
  dirName,
9841
10254
  frontmatter,
9842
10255
  body,
@@ -9865,7 +10278,7 @@ var CursorSkill = class _CursorSkill extends ToolSkill {
9865
10278
  }
9866
10279
  static getSettablePaths(_options) {
9867
10280
  return {
9868
- relativeDirPath: join71(".cursor", "skills")
10281
+ relativeDirPath: join73(".cursor", "skills")
9869
10282
  };
9870
10283
  }
9871
10284
  getFrontmatter() {
@@ -9945,9 +10358,9 @@ var CursorSkill = class _CursorSkill extends ToolSkill {
9945
10358
  });
9946
10359
  const result = CursorSkillFrontmatterSchema.safeParse(loaded.frontmatter);
9947
10360
  if (!result.success) {
9948
- const skillDirPath = join71(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10361
+ const skillDirPath = join73(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
9949
10362
  throw new Error(
9950
- `Invalid frontmatter in ${join71(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10363
+ `Invalid frontmatter in ${join73(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
9951
10364
  );
9952
10365
  }
9953
10366
  return new _CursorSkill({
@@ -9982,17 +10395,17 @@ var CursorSkill = class _CursorSkill extends ToolSkill {
9982
10395
  };
9983
10396
 
9984
10397
  // src/features/skills/deepagents-skill.ts
9985
- import { join as join72 } from "path";
9986
- import { z as z33 } from "zod/mini";
9987
- var DeepagentsSkillFrontmatterSchema = z33.looseObject({
9988
- name: z33.string(),
9989
- description: z33.string(),
9990
- "allowed-tools": z33.optional(z33.array(z33.string()))
10398
+ import { join as join74 } from "path";
10399
+ import { z as z34 } from "zod/mini";
10400
+ var DeepagentsSkillFrontmatterSchema = z34.looseObject({
10401
+ name: z34.string(),
10402
+ description: z34.string(),
10403
+ "allowed-tools": z34.optional(z34.array(z34.string()))
9991
10404
  });
9992
10405
  var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
9993
10406
  constructor({
9994
10407
  baseDir = process.cwd(),
9995
- relativeDirPath = join72(".deepagents", "skills"),
10408
+ relativeDirPath = join74(".deepagents", "skills"),
9996
10409
  dirName,
9997
10410
  frontmatter,
9998
10411
  body,
@@ -10024,7 +10437,7 @@ var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
10024
10437
  throw new Error("DeepagentsSkill does not support global mode.");
10025
10438
  }
10026
10439
  return {
10027
- relativeDirPath: join72(".deepagents", "skills")
10440
+ relativeDirPath: join74(".deepagents", "skills")
10028
10441
  };
10029
10442
  }
10030
10443
  getFrontmatter() {
@@ -10108,9 +10521,9 @@ var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
10108
10521
  });
10109
10522
  const result = DeepagentsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10110
10523
  if (!result.success) {
10111
- const skillDirPath = join72(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10524
+ const skillDirPath = join74(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10112
10525
  throw new Error(
10113
- `Invalid frontmatter in ${join72(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10526
+ `Invalid frontmatter in ${join74(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10114
10527
  );
10115
10528
  }
10116
10529
  return new _DeepagentsSkill({
@@ -10145,11 +10558,11 @@ var DeepagentsSkill = class _DeepagentsSkill extends ToolSkill {
10145
10558
  };
10146
10559
 
10147
10560
  // src/features/skills/geminicli-skill.ts
10148
- import { join as join73 } from "path";
10149
- import { z as z34 } from "zod/mini";
10150
- var GeminiCliSkillFrontmatterSchema = z34.looseObject({
10151
- name: z34.string(),
10152
- description: z34.string()
10561
+ import { join as join75 } from "path";
10562
+ import { z as z35 } from "zod/mini";
10563
+ var GeminiCliSkillFrontmatterSchema = z35.looseObject({
10564
+ name: z35.string(),
10565
+ description: z35.string()
10153
10566
  });
10154
10567
  var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
10155
10568
  constructor({
@@ -10185,7 +10598,7 @@ var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
10185
10598
  global: _global = false
10186
10599
  } = {}) {
10187
10600
  return {
10188
- relativeDirPath: join73(".gemini", "skills")
10601
+ relativeDirPath: join75(".gemini", "skills")
10189
10602
  };
10190
10603
  }
10191
10604
  getFrontmatter() {
@@ -10265,9 +10678,9 @@ var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
10265
10678
  });
10266
10679
  const result = GeminiCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10267
10680
  if (!result.success) {
10268
- const skillDirPath = join73(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10681
+ const skillDirPath = join75(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10269
10682
  throw new Error(
10270
- `Invalid frontmatter in ${join73(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10683
+ `Invalid frontmatter in ${join75(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10271
10684
  );
10272
10685
  }
10273
10686
  return new _GeminiCliSkill({
@@ -10302,16 +10715,16 @@ var GeminiCliSkill = class _GeminiCliSkill extends ToolSkill {
10302
10715
  };
10303
10716
 
10304
10717
  // src/features/skills/junie-skill.ts
10305
- import { join as join74 } from "path";
10306
- import { z as z35 } from "zod/mini";
10307
- var JunieSkillFrontmatterSchema = z35.looseObject({
10308
- name: z35.string(),
10309
- description: z35.string()
10718
+ import { join as join76 } from "path";
10719
+ import { z as z36 } from "zod/mini";
10720
+ var JunieSkillFrontmatterSchema = z36.looseObject({
10721
+ name: z36.string(),
10722
+ description: z36.string()
10310
10723
  });
10311
10724
  var JunieSkill = class _JunieSkill extends ToolSkill {
10312
10725
  constructor({
10313
10726
  baseDir = process.cwd(),
10314
- relativeDirPath = join74(".junie", "skills"),
10727
+ relativeDirPath = join76(".junie", "skills"),
10315
10728
  dirName,
10316
10729
  frontmatter,
10317
10730
  body,
@@ -10343,7 +10756,7 @@ var JunieSkill = class _JunieSkill extends ToolSkill {
10343
10756
  throw new Error("JunieSkill does not support global mode.");
10344
10757
  }
10345
10758
  return {
10346
- relativeDirPath: join74(".junie", "skills")
10759
+ relativeDirPath: join76(".junie", "skills")
10347
10760
  };
10348
10761
  }
10349
10762
  getFrontmatter() {
@@ -10430,13 +10843,13 @@ var JunieSkill = class _JunieSkill extends ToolSkill {
10430
10843
  });
10431
10844
  const result = JunieSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10432
10845
  if (!result.success) {
10433
- const skillDirPath = join74(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10846
+ const skillDirPath = join76(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10434
10847
  throw new Error(
10435
- `Invalid frontmatter in ${join74(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10848
+ `Invalid frontmatter in ${join76(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10436
10849
  );
10437
10850
  }
10438
10851
  if (result.data.name !== loaded.dirName) {
10439
- const skillFilePath = join74(
10852
+ const skillFilePath = join76(
10440
10853
  loaded.baseDir,
10441
10854
  loaded.relativeDirPath,
10442
10855
  loaded.dirName,
@@ -10478,16 +10891,16 @@ var JunieSkill = class _JunieSkill extends ToolSkill {
10478
10891
  };
10479
10892
 
10480
10893
  // src/features/skills/kilo-skill.ts
10481
- import { join as join75 } from "path";
10482
- import { z as z36 } from "zod/mini";
10483
- var KiloSkillFrontmatterSchema = z36.looseObject({
10484
- name: z36.string(),
10485
- description: z36.string()
10894
+ import { join as join77 } from "path";
10895
+ import { z as z37 } from "zod/mini";
10896
+ var KiloSkillFrontmatterSchema = z37.looseObject({
10897
+ name: z37.string(),
10898
+ description: z37.string()
10486
10899
  });
10487
10900
  var KiloSkill = class _KiloSkill extends ToolSkill {
10488
10901
  constructor({
10489
10902
  baseDir = process.cwd(),
10490
- relativeDirPath = join75(".kilocode", "skills"),
10903
+ relativeDirPath = join77(".kilocode", "skills"),
10491
10904
  dirName,
10492
10905
  frontmatter,
10493
10906
  body,
@@ -10518,7 +10931,7 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
10518
10931
  global: _global = false
10519
10932
  } = {}) {
10520
10933
  return {
10521
- relativeDirPath: join75(".kilocode", "skills")
10934
+ relativeDirPath: join77(".kilocode", "skills")
10522
10935
  };
10523
10936
  }
10524
10937
  getFrontmatter() {
@@ -10606,13 +11019,13 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
10606
11019
  });
10607
11020
  const result = KiloSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10608
11021
  if (!result.success) {
10609
- const skillDirPath = join75(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11022
+ const skillDirPath = join77(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10610
11023
  throw new Error(
10611
- `Invalid frontmatter in ${join75(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11024
+ `Invalid frontmatter in ${join77(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10612
11025
  );
10613
11026
  }
10614
11027
  if (result.data.name !== loaded.dirName) {
10615
- const skillFilePath = join75(
11028
+ const skillFilePath = join77(
10616
11029
  loaded.baseDir,
10617
11030
  loaded.relativeDirPath,
10618
11031
  loaded.dirName,
@@ -10653,16 +11066,16 @@ var KiloSkill = class _KiloSkill extends ToolSkill {
10653
11066
  };
10654
11067
 
10655
11068
  // src/features/skills/kiro-skill.ts
10656
- import { join as join76 } from "path";
10657
- import { z as z37 } from "zod/mini";
10658
- var KiroSkillFrontmatterSchema = z37.looseObject({
10659
- name: z37.string(),
10660
- description: z37.string()
11069
+ import { join as join78 } from "path";
11070
+ import { z as z38 } from "zod/mini";
11071
+ var KiroSkillFrontmatterSchema = z38.looseObject({
11072
+ name: z38.string(),
11073
+ description: z38.string()
10661
11074
  });
10662
11075
  var KiroSkill = class _KiroSkill extends ToolSkill {
10663
11076
  constructor({
10664
11077
  baseDir = process.cwd(),
10665
- relativeDirPath = join76(".kiro", "skills"),
11078
+ relativeDirPath = join78(".kiro", "skills"),
10666
11079
  dirName,
10667
11080
  frontmatter,
10668
11081
  body,
@@ -10694,7 +11107,7 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
10694
11107
  throw new Error("KiroSkill does not support global mode.");
10695
11108
  }
10696
11109
  return {
10697
- relativeDirPath: join76(".kiro", "skills")
11110
+ relativeDirPath: join78(".kiro", "skills")
10698
11111
  };
10699
11112
  }
10700
11113
  getFrontmatter() {
@@ -10782,13 +11195,13 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
10782
11195
  });
10783
11196
  const result = KiroSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10784
11197
  if (!result.success) {
10785
- const skillDirPath = join76(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11198
+ const skillDirPath = join78(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10786
11199
  throw new Error(
10787
- `Invalid frontmatter in ${join76(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11200
+ `Invalid frontmatter in ${join78(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10788
11201
  );
10789
11202
  }
10790
11203
  if (result.data.name !== loaded.dirName) {
10791
- const skillFilePath = join76(
11204
+ const skillFilePath = join78(
10792
11205
  loaded.baseDir,
10793
11206
  loaded.relativeDirPath,
10794
11207
  loaded.dirName,
@@ -10830,17 +11243,17 @@ var KiroSkill = class _KiroSkill extends ToolSkill {
10830
11243
  };
10831
11244
 
10832
11245
  // src/features/skills/opencode-skill.ts
10833
- import { join as join77 } from "path";
10834
- import { z as z38 } from "zod/mini";
10835
- var OpenCodeSkillFrontmatterSchema = z38.looseObject({
10836
- name: z38.string(),
10837
- description: z38.string(),
10838
- "allowed-tools": z38.optional(z38.array(z38.string()))
11246
+ import { join as join79 } from "path";
11247
+ import { z as z39 } from "zod/mini";
11248
+ var OpenCodeSkillFrontmatterSchema = z39.looseObject({
11249
+ name: z39.string(),
11250
+ description: z39.string(),
11251
+ "allowed-tools": z39.optional(z39.array(z39.string()))
10839
11252
  });
10840
11253
  var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
10841
11254
  constructor({
10842
11255
  baseDir = process.cwd(),
10843
- relativeDirPath = join77(".opencode", "skill"),
11256
+ relativeDirPath = join79(".opencode", "skill"),
10844
11257
  dirName,
10845
11258
  frontmatter,
10846
11259
  body,
@@ -10869,7 +11282,7 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
10869
11282
  }
10870
11283
  static getSettablePaths({ global = false } = {}) {
10871
11284
  return {
10872
- relativeDirPath: global ? join77(".config", "opencode", "skill") : join77(".opencode", "skill")
11285
+ relativeDirPath: global ? join79(".config", "opencode", "skill") : join79(".opencode", "skill")
10873
11286
  };
10874
11287
  }
10875
11288
  getFrontmatter() {
@@ -10955,9 +11368,9 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
10955
11368
  });
10956
11369
  const result = OpenCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
10957
11370
  if (!result.success) {
10958
- const skillDirPath = join77(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11371
+ const skillDirPath = join79(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
10959
11372
  throw new Error(
10960
- `Invalid frontmatter in ${join77(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11373
+ `Invalid frontmatter in ${join79(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
10961
11374
  );
10962
11375
  }
10963
11376
  return new _OpenCodeSkill({
@@ -10991,16 +11404,16 @@ var OpenCodeSkill = class _OpenCodeSkill extends ToolSkill {
10991
11404
  };
10992
11405
 
10993
11406
  // src/features/skills/replit-skill.ts
10994
- import { join as join78 } from "path";
10995
- import { z as z39 } from "zod/mini";
10996
- var ReplitSkillFrontmatterSchema = z39.looseObject({
10997
- name: z39.string(),
10998
- description: z39.string()
11407
+ import { join as join80 } from "path";
11408
+ import { z as z40 } from "zod/mini";
11409
+ var ReplitSkillFrontmatterSchema = z40.looseObject({
11410
+ name: z40.string(),
11411
+ description: z40.string()
10999
11412
  });
11000
11413
  var ReplitSkill = class _ReplitSkill extends ToolSkill {
11001
11414
  constructor({
11002
11415
  baseDir = process.cwd(),
11003
- relativeDirPath = join78(".agents", "skills"),
11416
+ relativeDirPath = join80(".agents", "skills"),
11004
11417
  dirName,
11005
11418
  frontmatter,
11006
11419
  body,
@@ -11032,7 +11445,7 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
11032
11445
  throw new Error("ReplitSkill does not support global mode.");
11033
11446
  }
11034
11447
  return {
11035
- relativeDirPath: join78(".agents", "skills")
11448
+ relativeDirPath: join80(".agents", "skills")
11036
11449
  };
11037
11450
  }
11038
11451
  getFrontmatter() {
@@ -11112,9 +11525,9 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
11112
11525
  });
11113
11526
  const result = ReplitSkillFrontmatterSchema.safeParse(loaded.frontmatter);
11114
11527
  if (!result.success) {
11115
- const skillDirPath = join78(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11528
+ const skillDirPath = join80(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11116
11529
  throw new Error(
11117
- `Invalid frontmatter in ${join78(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11530
+ `Invalid frontmatter in ${join80(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11118
11531
  );
11119
11532
  }
11120
11533
  return new _ReplitSkill({
@@ -11149,16 +11562,16 @@ var ReplitSkill = class _ReplitSkill extends ToolSkill {
11149
11562
  };
11150
11563
 
11151
11564
  // src/features/skills/roo-skill.ts
11152
- import { join as join79 } from "path";
11153
- import { z as z40 } from "zod/mini";
11154
- var RooSkillFrontmatterSchema = z40.looseObject({
11155
- name: z40.string(),
11156
- description: z40.string()
11565
+ import { join as join81 } from "path";
11566
+ import { z as z41 } from "zod/mini";
11567
+ var RooSkillFrontmatterSchema = z41.looseObject({
11568
+ name: z41.string(),
11569
+ description: z41.string()
11157
11570
  });
11158
11571
  var RooSkill = class _RooSkill extends ToolSkill {
11159
11572
  constructor({
11160
11573
  baseDir = process.cwd(),
11161
- relativeDirPath = join79(".roo", "skills"),
11574
+ relativeDirPath = join81(".roo", "skills"),
11162
11575
  dirName,
11163
11576
  frontmatter,
11164
11577
  body,
@@ -11189,7 +11602,7 @@ var RooSkill = class _RooSkill extends ToolSkill {
11189
11602
  global: _global = false
11190
11603
  } = {}) {
11191
11604
  return {
11192
- relativeDirPath: join79(".roo", "skills")
11605
+ relativeDirPath: join81(".roo", "skills")
11193
11606
  };
11194
11607
  }
11195
11608
  getFrontmatter() {
@@ -11277,13 +11690,13 @@ var RooSkill = class _RooSkill extends ToolSkill {
11277
11690
  });
11278
11691
  const result = RooSkillFrontmatterSchema.safeParse(loaded.frontmatter);
11279
11692
  if (!result.success) {
11280
- const skillDirPath = join79(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11693
+ const skillDirPath = join81(loaded.baseDir, loaded.relativeDirPath, loaded.dirName);
11281
11694
  throw new Error(
11282
- `Invalid frontmatter in ${join79(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11695
+ `Invalid frontmatter in ${join81(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`
11283
11696
  );
11284
11697
  }
11285
11698
  if (result.data.name !== loaded.dirName) {
11286
- const skillFilePath = join79(
11699
+ const skillFilePath = join81(
11287
11700
  loaded.baseDir,
11288
11701
  loaded.relativeDirPath,
11289
11702
  loaded.dirName,
@@ -11324,14 +11737,14 @@ var RooSkill = class _RooSkill extends ToolSkill {
11324
11737
  };
11325
11738
 
11326
11739
  // src/features/skills/skills-utils.ts
11327
- import { basename as basename4, join as join80 } from "path";
11740
+ import { basename as basename4, join as join82 } from "path";
11328
11741
  async function getLocalSkillDirNames(baseDir) {
11329
- const skillsDir = join80(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
11742
+ const skillsDir = join82(baseDir, RULESYNC_SKILLS_RELATIVE_DIR_PATH);
11330
11743
  const names = /* @__PURE__ */ new Set();
11331
11744
  if (!await directoryExists(skillsDir)) {
11332
11745
  return names;
11333
11746
  }
11334
- const dirPaths = await findFilesByGlobs(join80(skillsDir, "*"), { type: "dir" });
11747
+ const dirPaths = await findFilesByGlobs(join82(skillsDir, "*"), { type: "dir" });
11335
11748
  for (const dirPath of dirPaths) {
11336
11749
  const name = basename4(dirPath);
11337
11750
  if (name === basename4(RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH)) continue;
@@ -11359,9 +11772,10 @@ var skillsProcessorToolTargetTuple = [
11359
11772
  "kiro",
11360
11773
  "opencode",
11361
11774
  "replit",
11362
- "roo"
11775
+ "roo",
11776
+ "rovodev"
11363
11777
  ];
11364
- var SkillsProcessorToolTargetSchema = z41.enum(skillsProcessorToolTargetTuple);
11778
+ var SkillsProcessorToolTargetSchema = z42.enum(skillsProcessorToolTargetTuple);
11365
11779
  var toolSkillFactories = /* @__PURE__ */ new Map([
11366
11780
  [
11367
11781
  "agentsmd",
@@ -11488,6 +11902,13 @@ var toolSkillFactories = /* @__PURE__ */ new Map([
11488
11902
  class: RooSkill,
11489
11903
  meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: true }
11490
11904
  }
11905
+ ],
11906
+ [
11907
+ "rovodev",
11908
+ {
11909
+ class: RovodevSkill,
11910
+ meta: { supportsProject: true, supportsSimulated: false, supportsGlobal: true }
11911
+ }
11491
11912
  ]
11492
11913
  ]);
11493
11914
  var defaultGetFactory4 = (target) => {
@@ -11578,10 +11999,10 @@ var SkillsProcessor = class extends DirFeatureProcessor {
11578
11999
  )
11579
12000
  );
11580
12001
  const localSkillNames = new Set(localDirNames);
11581
- const curatedDirPath = join81(process.cwd(), RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
12002
+ const curatedDirPath = join83(process.cwd(), RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
11582
12003
  let curatedSkills = [];
11583
12004
  if (await directoryExists(curatedDirPath)) {
11584
- const curatedDirPaths = await findFilesByGlobs(join81(curatedDirPath, "*"), { type: "dir" });
12005
+ const curatedDirPaths = await findFilesByGlobs(join83(curatedDirPath, "*"), { type: "dir" });
11585
12006
  const curatedDirNames = curatedDirPaths.map((path3) => basename5(path3));
11586
12007
  const nonConflicting = curatedDirNames.filter((name) => {
11587
12008
  if (localSkillNames.has(name)) {
@@ -11615,37 +12036,64 @@ var SkillsProcessor = class extends DirFeatureProcessor {
11615
12036
  async loadToolDirs() {
11616
12037
  const factory = this.getFactory(this.toolTarget);
11617
12038
  const paths = factory.class.getSettablePaths({ global: this.global });
11618
- const skillsDirPath = join81(this.baseDir, paths.relativeDirPath);
11619
- const dirPaths = await findFilesByGlobs(join81(skillsDirPath, "*"), { type: "dir" });
11620
- const dirNames = dirPaths.map((path3) => basename5(path3));
12039
+ const roots = toolSkillSearchRoots(paths);
12040
+ const seenDirNames = /* @__PURE__ */ new Set();
12041
+ const loadEntries = [];
12042
+ for (const root of roots) {
12043
+ const skillsDirPath = join83(this.baseDir, root);
12044
+ if (!await directoryExists(skillsDirPath)) {
12045
+ continue;
12046
+ }
12047
+ const dirPaths = await findFilesByGlobs(join83(skillsDirPath, "*"), { type: "dir" });
12048
+ for (const dirPath of dirPaths) {
12049
+ const dirName = basename5(dirPath);
12050
+ if (seenDirNames.has(dirName)) {
12051
+ continue;
12052
+ }
12053
+ seenDirNames.add(dirName);
12054
+ loadEntries.push({ root, dirName });
12055
+ }
12056
+ }
11621
12057
  const toolSkills = await Promise.all(
11622
- dirNames.map(
11623
- (dirName) => factory.class.fromDir({
12058
+ loadEntries.map(
12059
+ ({ root, dirName }) => factory.class.fromDir({
11624
12060
  baseDir: this.baseDir,
12061
+ relativeDirPath: root,
11625
12062
  dirName,
11626
12063
  global: this.global
11627
12064
  })
11628
12065
  )
11629
12066
  );
11630
- this.logger.debug(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
12067
+ this.logger.debug(
12068
+ `Successfully loaded ${toolSkills.length} skills from ${roots.length} root(s): ${roots.join(", ")}`
12069
+ );
11631
12070
  return toolSkills;
11632
12071
  }
11633
12072
  async loadToolDirsToDelete() {
11634
12073
  const factory = this.getFactory(this.toolTarget);
11635
12074
  const paths = factory.class.getSettablePaths({ global: this.global });
11636
- const skillsDirPath = join81(this.baseDir, paths.relativeDirPath);
11637
- const dirPaths = await findFilesByGlobs(join81(skillsDirPath, "*"), { type: "dir" });
11638
- const dirNames = dirPaths.map((path3) => basename5(path3));
11639
- const toolSkills = dirNames.map(
11640
- (dirName) => factory.class.forDeletion({
11641
- baseDir: this.baseDir,
11642
- relativeDirPath: paths.relativeDirPath,
11643
- dirName,
11644
- global: this.global
11645
- })
11646
- );
12075
+ const roots = toolSkillSearchRoots(paths);
12076
+ const toolSkills = [];
12077
+ for (const root of roots) {
12078
+ const skillsDirPath = join83(this.baseDir, root);
12079
+ if (!await directoryExists(skillsDirPath)) {
12080
+ continue;
12081
+ }
12082
+ const dirPaths = await findFilesByGlobs(join83(skillsDirPath, "*"), { type: "dir" });
12083
+ for (const dirPath of dirPaths) {
12084
+ const dirName = basename5(dirPath);
12085
+ toolSkills.push(
12086
+ factory.class.forDeletion({
12087
+ baseDir: this.baseDir,
12088
+ relativeDirPath: root,
12089
+ dirName,
12090
+ global: this.global
12091
+ })
12092
+ );
12093
+ }
12094
+ }
11647
12095
  this.logger.debug(
11648
- `Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills for deletion`
12096
+ `Successfully loaded ${toolSkills.length} skills for deletion under ${roots.join(", ")}`
11649
12097
  );
11650
12098
  return toolSkills;
11651
12099
  }
@@ -11696,11 +12144,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
11696
12144
  };
11697
12145
 
11698
12146
  // src/features/subagents/agentsmd-subagent.ts
11699
- import { join as join83 } from "path";
12147
+ import { join as join85 } from "path";
11700
12148
 
11701
12149
  // src/features/subagents/simulated-subagent.ts
11702
- import { basename as basename6, join as join82 } from "path";
11703
- import { z as z42 } from "zod/mini";
12150
+ import { basename as basename6, join as join84 } from "path";
12151
+ import { z as z43 } from "zod/mini";
11704
12152
 
11705
12153
  // src/features/subagents/tool-subagent.ts
11706
12154
  var ToolSubagent = class extends ToolFile {
@@ -11752,9 +12200,9 @@ var ToolSubagent = class extends ToolFile {
11752
12200
  };
11753
12201
 
11754
12202
  // src/features/subagents/simulated-subagent.ts
11755
- var SimulatedSubagentFrontmatterSchema = z42.object({
11756
- name: z42.string(),
11757
- description: z42.optional(z42.string())
12203
+ var SimulatedSubagentFrontmatterSchema = z43.object({
12204
+ name: z43.string(),
12205
+ description: z43.optional(z43.string())
11758
12206
  });
11759
12207
  var SimulatedSubagent = class extends ToolSubagent {
11760
12208
  frontmatter;
@@ -11764,7 +12212,7 @@ var SimulatedSubagent = class extends ToolSubagent {
11764
12212
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
11765
12213
  if (!result.success) {
11766
12214
  throw new Error(
11767
- `Invalid frontmatter in ${join82(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12215
+ `Invalid frontmatter in ${join84(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
11768
12216
  );
11769
12217
  }
11770
12218
  }
@@ -11815,7 +12263,7 @@ var SimulatedSubagent = class extends ToolSubagent {
11815
12263
  return {
11816
12264
  success: false,
11817
12265
  error: new Error(
11818
- `Invalid frontmatter in ${join82(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12266
+ `Invalid frontmatter in ${join84(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
11819
12267
  )
11820
12268
  };
11821
12269
  }
@@ -11825,7 +12273,7 @@ var SimulatedSubagent = class extends ToolSubagent {
11825
12273
  relativeFilePath,
11826
12274
  validate = true
11827
12275
  }) {
11828
- const filePath = join82(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
12276
+ const filePath = join84(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
11829
12277
  const fileContent = await readFileContent(filePath);
11830
12278
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
11831
12279
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -11861,7 +12309,7 @@ var SimulatedSubagent = class extends ToolSubagent {
11861
12309
  var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
11862
12310
  static getSettablePaths() {
11863
12311
  return {
11864
- relativeDirPath: join83(".agents", "subagents")
12312
+ relativeDirPath: join85(".agents", "subagents")
11865
12313
  };
11866
12314
  }
11867
12315
  static async fromFile(params) {
@@ -11884,11 +12332,11 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
11884
12332
  };
11885
12333
 
11886
12334
  // src/features/subagents/factorydroid-subagent.ts
11887
- import { join as join84 } from "path";
12335
+ import { join as join86 } from "path";
11888
12336
  var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent {
11889
12337
  static getSettablePaths(_options) {
11890
12338
  return {
11891
- relativeDirPath: join84(".factory", "droids")
12339
+ relativeDirPath: join86(".factory", "droids")
11892
12340
  };
11893
12341
  }
11894
12342
  static async fromFile(params) {
@@ -11911,11 +12359,11 @@ var FactorydroidSubagent = class _FactorydroidSubagent extends SimulatedSubagent
11911
12359
  };
11912
12360
 
11913
12361
  // src/features/subagents/geminicli-subagent.ts
11914
- import { join as join85 } from "path";
12362
+ import { join as join87 } from "path";
11915
12363
  var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
11916
12364
  static getSettablePaths() {
11917
12365
  return {
11918
- relativeDirPath: join85(".gemini", "subagents")
12366
+ relativeDirPath: join87(".gemini", "subagents")
11919
12367
  };
11920
12368
  }
11921
12369
  static async fromFile(params) {
@@ -11938,11 +12386,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
11938
12386
  };
11939
12387
 
11940
12388
  // src/features/subagents/roo-subagent.ts
11941
- import { join as join86 } from "path";
12389
+ import { join as join88 } from "path";
11942
12390
  var RooSubagent = class _RooSubagent extends SimulatedSubagent {
11943
12391
  static getSettablePaths() {
11944
12392
  return {
11945
- relativeDirPath: join86(".roo", "subagents")
12393
+ relativeDirPath: join88(".roo", "subagents")
11946
12394
  };
11947
12395
  }
11948
12396
  static async fromFile(params) {
@@ -11964,21 +12412,17 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
11964
12412
  }
11965
12413
  };
11966
12414
 
11967
- // src/features/subagents/subagents-processor.ts
11968
- import { basename as basename9, join as join96 } from "path";
11969
- import { z as z52 } from "zod/mini";
11970
-
11971
- // src/features/subagents/claudecode-subagent.ts
11972
- import { join as join88 } from "path";
11973
- import { z as z44 } from "zod/mini";
12415
+ // src/features/subagents/rovodev-subagent.ts
12416
+ import { join as join90 } from "path";
12417
+ import { z as z45 } from "zod/mini";
11974
12418
 
11975
12419
  // src/features/subagents/rulesync-subagent.ts
11976
- import { basename as basename7, join as join87 } from "path";
11977
- import { z as z43 } from "zod/mini";
11978
- var RulesyncSubagentFrontmatterSchema = z43.looseObject({
11979
- targets: z43._default(RulesyncTargetsSchema, ["*"]),
11980
- name: z43.string(),
11981
- description: z43.optional(z43.string())
12420
+ import { basename as basename7, join as join89 } from "path";
12421
+ import { z as z44 } from "zod/mini";
12422
+ var RulesyncSubagentFrontmatterSchema = z44.looseObject({
12423
+ targets: z44._default(RulesyncTargetsSchema, ["*"]),
12424
+ name: z44.string(),
12425
+ description: z44.optional(z44.string())
11982
12426
  });
11983
12427
  var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
11984
12428
  frontmatter;
@@ -11987,7 +12431,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
11987
12431
  const parseResult = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
11988
12432
  if (!parseResult.success && rest.validate !== false) {
11989
12433
  throw new Error(
11990
- `Invalid frontmatter in ${join87(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
12434
+ `Invalid frontmatter in ${join89(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
11991
12435
  );
11992
12436
  }
11993
12437
  const parsedFrontmatter = parseResult.success ? { ...frontmatter, ...parseResult.data } : { ...frontmatter, targets: frontmatter?.targets ?? ["*"] };
@@ -12020,7 +12464,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
12020
12464
  return {
12021
12465
  success: false,
12022
12466
  error: new Error(
12023
- `Invalid frontmatter in ${join87(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12467
+ `Invalid frontmatter in ${join89(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12024
12468
  )
12025
12469
  };
12026
12470
  }
@@ -12028,7 +12472,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
12028
12472
  static async fromFile({
12029
12473
  relativeFilePath
12030
12474
  }) {
12031
- const filePath = join87(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath);
12475
+ const filePath = join89(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath);
12032
12476
  const fileContent = await readFileContent(filePath);
12033
12477
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12034
12478
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12046,14 +12490,163 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
12046
12490
  }
12047
12491
  };
12048
12492
 
12493
+ // src/features/subagents/rovodev-subagent.ts
12494
+ var RovodevSubagentFrontmatterSchema = z45.looseObject({
12495
+ name: z45.string(),
12496
+ description: z45.optional(z45.string())
12497
+ });
12498
+ var RovodevSubagent = class _RovodevSubagent extends ToolSubagent {
12499
+ frontmatter;
12500
+ body;
12501
+ constructor({ frontmatter, body, ...rest }) {
12502
+ if (rest.validate !== false) {
12503
+ const result = RovodevSubagentFrontmatterSchema.safeParse(frontmatter);
12504
+ if (!result.success) {
12505
+ throw new Error(
12506
+ `Invalid frontmatter in ${join90(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12507
+ );
12508
+ }
12509
+ }
12510
+ super({
12511
+ ...rest
12512
+ });
12513
+ this.frontmatter = frontmatter;
12514
+ this.body = body;
12515
+ }
12516
+ static getSettablePaths(_options = {}) {
12517
+ return {
12518
+ relativeDirPath: join90(".rovodev", "subagents")
12519
+ };
12520
+ }
12521
+ getFrontmatter() {
12522
+ return this.frontmatter;
12523
+ }
12524
+ getBody() {
12525
+ return this.body;
12526
+ }
12527
+ toRulesyncSubagent() {
12528
+ const { name, description, ...rest } = this.frontmatter;
12529
+ const rulesyncFrontmatter = {
12530
+ targets: ["*"],
12531
+ name,
12532
+ description,
12533
+ rovodev: {
12534
+ ...rest
12535
+ }
12536
+ };
12537
+ return new RulesyncSubagent({
12538
+ baseDir: ".",
12539
+ frontmatter: rulesyncFrontmatter,
12540
+ body: this.body,
12541
+ relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
12542
+ relativeFilePath: this.getRelativeFilePath(),
12543
+ validate: true
12544
+ });
12545
+ }
12546
+ static fromRulesyncSubagent({
12547
+ baseDir = process.cwd(),
12548
+ rulesyncSubagent,
12549
+ validate = true,
12550
+ global = false
12551
+ }) {
12552
+ const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
12553
+ const rovodevSection = rulesyncFrontmatter.rovodev ?? {};
12554
+ const rovodevFrontmatter = {
12555
+ name: rulesyncFrontmatter.name,
12556
+ description: rulesyncFrontmatter.description,
12557
+ ...rovodevSection
12558
+ };
12559
+ const body = rulesyncSubagent.getBody();
12560
+ const fileContent = stringifyFrontmatter(body, rovodevFrontmatter, { avoidBlockScalars: true });
12561
+ const paths = this.getSettablePaths({ global });
12562
+ return new _RovodevSubagent({
12563
+ baseDir,
12564
+ frontmatter: rovodevFrontmatter,
12565
+ body,
12566
+ relativeDirPath: paths.relativeDirPath,
12567
+ relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
12568
+ fileContent,
12569
+ validate,
12570
+ global
12571
+ });
12572
+ }
12573
+ validate() {
12574
+ const result = RovodevSubagentFrontmatterSchema.safeParse(this.frontmatter);
12575
+ if (result.success) {
12576
+ return { success: true, error: null };
12577
+ }
12578
+ return {
12579
+ success: false,
12580
+ error: new Error(
12581
+ `Invalid frontmatter in ${join90(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12582
+ )
12583
+ };
12584
+ }
12585
+ static isTargetedByRulesyncSubagent(rulesyncSubagent) {
12586
+ return this.isTargetedByRulesyncSubagentDefault({
12587
+ rulesyncSubagent,
12588
+ toolTarget: "rovodev"
12589
+ });
12590
+ }
12591
+ static async fromFile({
12592
+ baseDir = process.cwd(),
12593
+ relativeFilePath,
12594
+ validate = true,
12595
+ global = false
12596
+ }) {
12597
+ const paths = this.getSettablePaths({ global });
12598
+ const filePath = join90(baseDir, paths.relativeDirPath, relativeFilePath);
12599
+ const fileContent = await readFileContent(filePath);
12600
+ const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12601
+ const result = RovodevSubagentFrontmatterSchema.safeParse(frontmatter);
12602
+ if (!result.success) {
12603
+ throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
12604
+ }
12605
+ return new _RovodevSubagent({
12606
+ baseDir,
12607
+ relativeDirPath: paths.relativeDirPath,
12608
+ relativeFilePath,
12609
+ frontmatter: result.data,
12610
+ body: content.trim(),
12611
+ fileContent,
12612
+ validate,
12613
+ global
12614
+ });
12615
+ }
12616
+ static forDeletion({
12617
+ baseDir = process.cwd(),
12618
+ relativeDirPath,
12619
+ relativeFilePath,
12620
+ global = false
12621
+ }) {
12622
+ const paths = this.getSettablePaths({ global });
12623
+ return new _RovodevSubagent({
12624
+ baseDir,
12625
+ relativeDirPath: relativeDirPath ?? paths.relativeDirPath,
12626
+ relativeFilePath,
12627
+ frontmatter: { name: "", description: "" },
12628
+ body: "",
12629
+ fileContent: "",
12630
+ validate: false,
12631
+ global
12632
+ });
12633
+ }
12634
+ };
12635
+
12636
+ // src/features/subagents/subagents-processor.ts
12637
+ import { basename as basename9, join as join99 } from "path";
12638
+ import { z as z54 } from "zod/mini";
12639
+
12049
12640
  // src/features/subagents/claudecode-subagent.ts
12050
- var ClaudecodeSubagentFrontmatterSchema = z44.looseObject({
12051
- name: z44.string(),
12052
- description: z44.optional(z44.string()),
12053
- model: z44.optional(z44.string()),
12054
- tools: z44.optional(z44.union([z44.string(), z44.array(z44.string())])),
12055
- permissionMode: z44.optional(z44.string()),
12056
- skills: z44.optional(z44.union([z44.string(), z44.array(z44.string())]))
12641
+ import { join as join91 } from "path";
12642
+ import { z as z46 } from "zod/mini";
12643
+ var ClaudecodeSubagentFrontmatterSchema = z46.looseObject({
12644
+ name: z46.string(),
12645
+ description: z46.optional(z46.string()),
12646
+ model: z46.optional(z46.string()),
12647
+ tools: z46.optional(z46.union([z46.string(), z46.array(z46.string())])),
12648
+ permissionMode: z46.optional(z46.string()),
12649
+ skills: z46.optional(z46.union([z46.string(), z46.array(z46.string())]))
12057
12650
  });
12058
12651
  var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12059
12652
  frontmatter;
@@ -12063,7 +12656,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12063
12656
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
12064
12657
  if (!result.success) {
12065
12658
  throw new Error(
12066
- `Invalid frontmatter in ${join88(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12659
+ `Invalid frontmatter in ${join91(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12067
12660
  );
12068
12661
  }
12069
12662
  }
@@ -12075,7 +12668,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12075
12668
  }
12076
12669
  static getSettablePaths(_options = {}) {
12077
12670
  return {
12078
- relativeDirPath: join88(".claude", "agents")
12671
+ relativeDirPath: join91(".claude", "agents")
12079
12672
  };
12080
12673
  }
12081
12674
  getFrontmatter() {
@@ -12154,7 +12747,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12154
12747
  return {
12155
12748
  success: false,
12156
12749
  error: new Error(
12157
- `Invalid frontmatter in ${join88(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12750
+ `Invalid frontmatter in ${join91(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12158
12751
  )
12159
12752
  };
12160
12753
  }
@@ -12172,7 +12765,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12172
12765
  global = false
12173
12766
  }) {
12174
12767
  const paths = this.getSettablePaths({ global });
12175
- const filePath = join88(baseDir, paths.relativeDirPath, relativeFilePath);
12768
+ const filePath = join91(baseDir, paths.relativeDirPath, relativeFilePath);
12176
12769
  const fileContent = await readFileContent(filePath);
12177
12770
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12178
12771
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12207,27 +12800,27 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
12207
12800
  };
12208
12801
 
12209
12802
  // src/features/subagents/codexcli-subagent.ts
12210
- import { join as join89 } from "path";
12211
- import * as smolToml2 from "smol-toml";
12212
- import { z as z45 } from "zod/mini";
12213
- var CodexCliSubagentTomlSchema = z45.looseObject({
12214
- name: z45.string(),
12215
- description: z45.optional(z45.string()),
12216
- developer_instructions: z45.optional(z45.string()),
12217
- model: z45.optional(z45.string()),
12218
- model_reasoning_effort: z45.optional(z45.string()),
12219
- sandbox_mode: z45.optional(z45.string())
12803
+ import { join as join92 } from "path";
12804
+ import * as smolToml3 from "smol-toml";
12805
+ import { z as z47 } from "zod/mini";
12806
+ var CodexCliSubagentTomlSchema = z47.looseObject({
12807
+ name: z47.string(),
12808
+ description: z47.optional(z47.string()),
12809
+ developer_instructions: z47.optional(z47.string()),
12810
+ model: z47.optional(z47.string()),
12811
+ model_reasoning_effort: z47.optional(z47.string()),
12812
+ sandbox_mode: z47.optional(z47.string())
12220
12813
  });
12221
12814
  var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12222
12815
  body;
12223
12816
  constructor({ body, ...rest }) {
12224
12817
  if (rest.validate !== false) {
12225
12818
  try {
12226
- const parsed = smolToml2.parse(body);
12819
+ const parsed = smolToml3.parse(body);
12227
12820
  CodexCliSubagentTomlSchema.parse(parsed);
12228
12821
  } catch (error) {
12229
12822
  throw new Error(
12230
- `Invalid TOML in ${join89(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
12823
+ `Invalid TOML in ${join92(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
12231
12824
  { cause: error }
12232
12825
  );
12233
12826
  }
@@ -12239,7 +12832,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12239
12832
  }
12240
12833
  static getSettablePaths(_options = {}) {
12241
12834
  return {
12242
- relativeDirPath: join89(".codex", "agents")
12835
+ relativeDirPath: join92(".codex", "agents")
12243
12836
  };
12244
12837
  }
12245
12838
  getBody() {
@@ -12248,10 +12841,10 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12248
12841
  toRulesyncSubagent() {
12249
12842
  let parsed;
12250
12843
  try {
12251
- parsed = CodexCliSubagentTomlSchema.parse(smolToml2.parse(this.body));
12844
+ parsed = CodexCliSubagentTomlSchema.parse(smolToml3.parse(this.body));
12252
12845
  } catch (error) {
12253
12846
  throw new Error(
12254
- `Failed to parse TOML in ${join89(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
12847
+ `Failed to parse TOML in ${join92(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
12255
12848
  { cause: error }
12256
12849
  );
12257
12850
  }
@@ -12294,7 +12887,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12294
12887
  ...rulesyncSubagent.getBody() ? { developer_instructions: rulesyncSubagent.getBody() } : {},
12295
12888
  ...codexcliSection
12296
12889
  };
12297
- const body = smolToml2.stringify(tomlObj);
12890
+ const body = smolToml3.stringify(tomlObj);
12298
12891
  const paths = this.getSettablePaths({ global });
12299
12892
  const relativeFilePath = rulesyncSubagent.getRelativeFilePath().replace(/\.md$/, ".toml");
12300
12893
  return new _CodexCliSubagent({
@@ -12309,7 +12902,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12309
12902
  }
12310
12903
  validate() {
12311
12904
  try {
12312
- const parsed = smolToml2.parse(this.body);
12905
+ const parsed = smolToml3.parse(this.body);
12313
12906
  CodexCliSubagentTomlSchema.parse(parsed);
12314
12907
  return { success: true, error: null };
12315
12908
  } catch (error) {
@@ -12332,7 +12925,7 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12332
12925
  global = false
12333
12926
  }) {
12334
12927
  const paths = this.getSettablePaths({ global });
12335
- const filePath = join89(baseDir, paths.relativeDirPath, relativeFilePath);
12928
+ const filePath = join92(baseDir, paths.relativeDirPath, relativeFilePath);
12336
12929
  const fileContent = await readFileContent(filePath);
12337
12930
  const subagent = new _CodexCliSubagent({
12338
12931
  baseDir,
@@ -12370,13 +12963,13 @@ var CodexCliSubagent = class _CodexCliSubagent extends ToolSubagent {
12370
12963
  };
12371
12964
 
12372
12965
  // src/features/subagents/copilot-subagent.ts
12373
- import { join as join90 } from "path";
12374
- import { z as z46 } from "zod/mini";
12966
+ import { join as join93 } from "path";
12967
+ import { z as z48 } from "zod/mini";
12375
12968
  var REQUIRED_TOOL = "agent/runSubagent";
12376
- var CopilotSubagentFrontmatterSchema = z46.looseObject({
12377
- name: z46.string(),
12378
- description: z46.optional(z46.string()),
12379
- tools: z46.optional(z46.union([z46.string(), z46.array(z46.string())]))
12969
+ var CopilotSubagentFrontmatterSchema = z48.looseObject({
12970
+ name: z48.string(),
12971
+ description: z48.optional(z48.string()),
12972
+ tools: z48.optional(z48.union([z48.string(), z48.array(z48.string())]))
12380
12973
  });
12381
12974
  var normalizeTools = (tools) => {
12382
12975
  if (!tools) {
@@ -12396,7 +12989,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
12396
12989
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
12397
12990
  if (!result.success) {
12398
12991
  throw new Error(
12399
- `Invalid frontmatter in ${join90(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12992
+ `Invalid frontmatter in ${join93(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12400
12993
  );
12401
12994
  }
12402
12995
  }
@@ -12408,7 +13001,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
12408
13001
  }
12409
13002
  static getSettablePaths(_options = {}) {
12410
13003
  return {
12411
- relativeDirPath: join90(".github", "agents")
13004
+ relativeDirPath: join93(".github", "agents")
12412
13005
  };
12413
13006
  }
12414
13007
  getFrontmatter() {
@@ -12482,7 +13075,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
12482
13075
  return {
12483
13076
  success: false,
12484
13077
  error: new Error(
12485
- `Invalid frontmatter in ${join90(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13078
+ `Invalid frontmatter in ${join93(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12486
13079
  )
12487
13080
  };
12488
13081
  }
@@ -12500,7 +13093,7 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
12500
13093
  global = false
12501
13094
  }) {
12502
13095
  const paths = this.getSettablePaths({ global });
12503
- const filePath = join90(baseDir, paths.relativeDirPath, relativeFilePath);
13096
+ const filePath = join93(baseDir, paths.relativeDirPath, relativeFilePath);
12504
13097
  const fileContent = await readFileContent(filePath);
12505
13098
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12506
13099
  const result = CopilotSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12536,11 +13129,11 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
12536
13129
  };
12537
13130
 
12538
13131
  // src/features/subagents/cursor-subagent.ts
12539
- import { join as join91 } from "path";
12540
- import { z as z47 } from "zod/mini";
12541
- var CursorSubagentFrontmatterSchema = z47.looseObject({
12542
- name: z47.string(),
12543
- description: z47.optional(z47.string())
13132
+ import { join as join94 } from "path";
13133
+ import { z as z49 } from "zod/mini";
13134
+ var CursorSubagentFrontmatterSchema = z49.looseObject({
13135
+ name: z49.string(),
13136
+ description: z49.optional(z49.string())
12544
13137
  });
12545
13138
  var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12546
13139
  frontmatter;
@@ -12550,7 +13143,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12550
13143
  const result = CursorSubagentFrontmatterSchema.safeParse(frontmatter);
12551
13144
  if (!result.success) {
12552
13145
  throw new Error(
12553
- `Invalid frontmatter in ${join91(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13146
+ `Invalid frontmatter in ${join94(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12554
13147
  );
12555
13148
  }
12556
13149
  }
@@ -12562,7 +13155,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12562
13155
  }
12563
13156
  static getSettablePaths(_options = {}) {
12564
13157
  return {
12565
- relativeDirPath: join91(".cursor", "agents")
13158
+ relativeDirPath: join94(".cursor", "agents")
12566
13159
  };
12567
13160
  }
12568
13161
  getFrontmatter() {
@@ -12629,7 +13222,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12629
13222
  return {
12630
13223
  success: false,
12631
13224
  error: new Error(
12632
- `Invalid frontmatter in ${join91(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13225
+ `Invalid frontmatter in ${join94(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12633
13226
  )
12634
13227
  };
12635
13228
  }
@@ -12647,7 +13240,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12647
13240
  global = false
12648
13241
  }) {
12649
13242
  const paths = this.getSettablePaths({ global });
12650
- const filePath = join91(baseDir, paths.relativeDirPath, relativeFilePath);
13243
+ const filePath = join94(baseDir, paths.relativeDirPath, relativeFilePath);
12651
13244
  const fileContent = await readFileContent(filePath);
12652
13245
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12653
13246
  const result = CursorSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12683,12 +13276,12 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
12683
13276
  };
12684
13277
 
12685
13278
  // src/features/subagents/deepagents-subagent.ts
12686
- import { join as join92 } from "path";
12687
- import { z as z48 } from "zod/mini";
12688
- var DeepagentsSubagentFrontmatterSchema = z48.looseObject({
12689
- name: z48.string(),
12690
- description: z48.optional(z48.string()),
12691
- model: z48.optional(z48.string())
13279
+ import { join as join95 } from "path";
13280
+ import { z as z50 } from "zod/mini";
13281
+ var DeepagentsSubagentFrontmatterSchema = z50.looseObject({
13282
+ name: z50.string(),
13283
+ description: z50.optional(z50.string()),
13284
+ model: z50.optional(z50.string())
12692
13285
  });
12693
13286
  var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12694
13287
  frontmatter;
@@ -12698,7 +13291,7 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12698
13291
  const result = DeepagentsSubagentFrontmatterSchema.safeParse(frontmatter);
12699
13292
  if (!result.success) {
12700
13293
  throw new Error(
12701
- `Invalid frontmatter in ${join92(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13294
+ `Invalid frontmatter in ${join95(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12702
13295
  );
12703
13296
  }
12704
13297
  }
@@ -12708,7 +13301,7 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12708
13301
  }
12709
13302
  static getSettablePaths(_options = {}) {
12710
13303
  return {
12711
- relativeDirPath: join92(".deepagents", "agents")
13304
+ relativeDirPath: join95(".deepagents", "agents")
12712
13305
  };
12713
13306
  }
12714
13307
  getFrontmatter() {
@@ -12783,7 +13376,7 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12783
13376
  return {
12784
13377
  success: false,
12785
13378
  error: new Error(
12786
- `Invalid frontmatter in ${join92(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13379
+ `Invalid frontmatter in ${join95(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12787
13380
  )
12788
13381
  };
12789
13382
  }
@@ -12801,7 +13394,7 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12801
13394
  global = false
12802
13395
  }) {
12803
13396
  const paths = this.getSettablePaths({ global });
12804
- const filePath = join92(baseDir, paths.relativeDirPath, relativeFilePath);
13397
+ const filePath = join95(baseDir, paths.relativeDirPath, relativeFilePath);
12805
13398
  const fileContent = await readFileContent(filePath);
12806
13399
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12807
13400
  const result = DeepagentsSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12836,11 +13429,11 @@ var DeepagentsSubagent = class _DeepagentsSubagent extends ToolSubagent {
12836
13429
  };
12837
13430
 
12838
13431
  // src/features/subagents/junie-subagent.ts
12839
- import { join as join93 } from "path";
12840
- import { z as z49 } from "zod/mini";
12841
- var JunieSubagentFrontmatterSchema = z49.looseObject({
12842
- name: z49.optional(z49.string()),
12843
- description: z49.string()
13432
+ import { join as join96 } from "path";
13433
+ import { z as z51 } from "zod/mini";
13434
+ var JunieSubagentFrontmatterSchema = z51.looseObject({
13435
+ name: z51.optional(z51.string()),
13436
+ description: z51.string()
12844
13437
  });
12845
13438
  var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12846
13439
  frontmatter;
@@ -12850,7 +13443,7 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12850
13443
  const result = JunieSubagentFrontmatterSchema.safeParse(frontmatter);
12851
13444
  if (!result.success) {
12852
13445
  throw new Error(
12853
- `Invalid frontmatter in ${join93(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13446
+ `Invalid frontmatter in ${join96(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
12854
13447
  );
12855
13448
  }
12856
13449
  }
@@ -12865,7 +13458,7 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12865
13458
  throw new Error("JunieSubagent does not support global mode.");
12866
13459
  }
12867
13460
  return {
12868
- relativeDirPath: join93(".junie", "agents")
13461
+ relativeDirPath: join96(".junie", "agents")
12869
13462
  };
12870
13463
  }
12871
13464
  getFrontmatter() {
@@ -12941,7 +13534,7 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12941
13534
  return {
12942
13535
  success: false,
12943
13536
  error: new Error(
12944
- `Invalid frontmatter in ${join93(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13537
+ `Invalid frontmatter in ${join96(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
12945
13538
  )
12946
13539
  };
12947
13540
  }
@@ -12959,7 +13552,7 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12959
13552
  global = false
12960
13553
  }) {
12961
13554
  const paths = this.getSettablePaths({ global });
12962
- const filePath = join93(baseDir, paths.relativeDirPath, relativeFilePath);
13555
+ const filePath = join96(baseDir, paths.relativeDirPath, relativeFilePath);
12963
13556
  const fileContent = await readFileContent(filePath);
12964
13557
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
12965
13558
  const result = JunieSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -12994,23 +13587,23 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
12994
13587
  };
12995
13588
 
12996
13589
  // src/features/subagents/kiro-subagent.ts
12997
- import { join as join94 } from "path";
12998
- import { z as z50 } from "zod/mini";
12999
- var KiroCliSubagentJsonSchema = z50.looseObject({
13000
- name: z50.string(),
13001
- description: z50.optional(z50.nullable(z50.string())),
13002
- prompt: z50.optional(z50.nullable(z50.string())),
13003
- tools: z50.optional(z50.nullable(z50.array(z50.string()))),
13004
- toolAliases: z50.optional(z50.nullable(z50.record(z50.string(), z50.string()))),
13005
- toolSettings: z50.optional(z50.nullable(z50.unknown())),
13006
- toolSchema: z50.optional(z50.nullable(z50.unknown())),
13007
- hooks: z50.optional(z50.nullable(z50.record(z50.string(), z50.array(z50.unknown())))),
13008
- model: z50.optional(z50.nullable(z50.string())),
13009
- mcpServers: z50.optional(z50.nullable(z50.record(z50.string(), z50.unknown()))),
13010
- useLegacyMcpJson: z50.optional(z50.nullable(z50.boolean())),
13011
- resources: z50.optional(z50.nullable(z50.array(z50.string()))),
13012
- allowedTools: z50.optional(z50.nullable(z50.array(z50.string()))),
13013
- includeMcpJson: z50.optional(z50.nullable(z50.boolean()))
13590
+ import { join as join97 } from "path";
13591
+ import { z as z52 } from "zod/mini";
13592
+ var KiroCliSubagentJsonSchema = z52.looseObject({
13593
+ name: z52.string(),
13594
+ description: z52.optional(z52.nullable(z52.string())),
13595
+ prompt: z52.optional(z52.nullable(z52.string())),
13596
+ tools: z52.optional(z52.nullable(z52.array(z52.string()))),
13597
+ toolAliases: z52.optional(z52.nullable(z52.record(z52.string(), z52.string()))),
13598
+ toolSettings: z52.optional(z52.nullable(z52.unknown())),
13599
+ toolSchema: z52.optional(z52.nullable(z52.unknown())),
13600
+ hooks: z52.optional(z52.nullable(z52.record(z52.string(), z52.array(z52.unknown())))),
13601
+ model: z52.optional(z52.nullable(z52.string())),
13602
+ mcpServers: z52.optional(z52.nullable(z52.record(z52.string(), z52.unknown()))),
13603
+ useLegacyMcpJson: z52.optional(z52.nullable(z52.boolean())),
13604
+ resources: z52.optional(z52.nullable(z52.array(z52.string()))),
13605
+ allowedTools: z52.optional(z52.nullable(z52.array(z52.string()))),
13606
+ includeMcpJson: z52.optional(z52.nullable(z52.boolean()))
13014
13607
  });
13015
13608
  var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13016
13609
  body;
@@ -13021,7 +13614,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13021
13614
  KiroCliSubagentJsonSchema.parse(parsed);
13022
13615
  } catch (error) {
13023
13616
  throw new Error(
13024
- `Invalid JSON in ${join94(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
13617
+ `Invalid JSON in ${join97(rest.relativeDirPath, rest.relativeFilePath)}: ${error instanceof Error ? error.message : String(error)}`,
13025
13618
  { cause: error }
13026
13619
  );
13027
13620
  }
@@ -13033,7 +13626,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13033
13626
  }
13034
13627
  static getSettablePaths(_options = {}) {
13035
13628
  return {
13036
- relativeDirPath: join94(".kiro", "agents")
13629
+ relativeDirPath: join97(".kiro", "agents")
13037
13630
  };
13038
13631
  }
13039
13632
  getBody() {
@@ -13045,7 +13638,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13045
13638
  parsed = JSON.parse(this.body);
13046
13639
  } catch (error) {
13047
13640
  throw new Error(
13048
- `Failed to parse JSON in ${join94(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
13641
+ `Failed to parse JSON in ${join97(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`,
13049
13642
  { cause: error }
13050
13643
  );
13051
13644
  }
@@ -13126,7 +13719,7 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13126
13719
  global = false
13127
13720
  }) {
13128
13721
  const paths = this.getSettablePaths({ global });
13129
- const filePath = join94(baseDir, paths.relativeDirPath, relativeFilePath);
13722
+ const filePath = join97(baseDir, paths.relativeDirPath, relativeFilePath);
13130
13723
  const fileContent = await readFileContent(filePath);
13131
13724
  const subagent = new _KiroSubagent({
13132
13725
  baseDir,
@@ -13164,12 +13757,12 @@ var KiroSubagent = class _KiroSubagent extends ToolSubagent {
13164
13757
  };
13165
13758
 
13166
13759
  // src/features/subagents/opencode-subagent.ts
13167
- import { basename as basename8, join as join95 } from "path";
13168
- import { z as z51 } from "zod/mini";
13169
- var OpenCodeSubagentFrontmatterSchema = z51.looseObject({
13170
- description: z51.optional(z51.string()),
13171
- mode: z51._default(z51.string(), "subagent"),
13172
- name: z51.optional(z51.string())
13760
+ import { basename as basename8, join as join98 } from "path";
13761
+ import { z as z53 } from "zod/mini";
13762
+ var OpenCodeSubagentFrontmatterSchema = z53.looseObject({
13763
+ description: z53.optional(z53.string()),
13764
+ mode: z53._default(z53.string(), "subagent"),
13765
+ name: z53.optional(z53.string())
13173
13766
  });
13174
13767
  var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
13175
13768
  frontmatter;
@@ -13179,7 +13772,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
13179
13772
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
13180
13773
  if (!result.success) {
13181
13774
  throw new Error(
13182
- `Invalid frontmatter in ${join95(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13775
+ `Invalid frontmatter in ${join98(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
13183
13776
  );
13184
13777
  }
13185
13778
  }
@@ -13193,7 +13786,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
13193
13786
  global = false
13194
13787
  } = {}) {
13195
13788
  return {
13196
- relativeDirPath: global ? join95(".config", "opencode", "agent") : join95(".opencode", "agent")
13789
+ relativeDirPath: global ? join98(".config", "opencode", "agent") : join98(".opencode", "agent")
13197
13790
  };
13198
13791
  }
13199
13792
  getFrontmatter() {
@@ -13259,7 +13852,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
13259
13852
  return {
13260
13853
  success: false,
13261
13854
  error: new Error(
13262
- `Invalid frontmatter in ${join95(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13855
+ `Invalid frontmatter in ${join98(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13263
13856
  )
13264
13857
  };
13265
13858
  }
@@ -13276,7 +13869,7 @@ var OpenCodeSubagent = class _OpenCodeSubagent extends ToolSubagent {
13276
13869
  global = false
13277
13870
  }) {
13278
13871
  const paths = this.getSettablePaths({ global });
13279
- const filePath = join95(baseDir, paths.relativeDirPath, relativeFilePath);
13872
+ const filePath = join98(baseDir, paths.relativeDirPath, relativeFilePath);
13280
13873
  const fileContent = await readFileContent(filePath);
13281
13874
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
13282
13875
  const result = OpenCodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -13325,9 +13918,10 @@ var subagentsProcessorToolTargetTuple = [
13325
13918
  "junie",
13326
13919
  "kiro",
13327
13920
  "opencode",
13328
- "roo"
13921
+ "roo",
13922
+ "rovodev"
13329
13923
  ];
13330
- var SubagentsProcessorToolTargetSchema = z52.enum(subagentsProcessorToolTargetTuple);
13924
+ var SubagentsProcessorToolTargetSchema = z54.enum(subagentsProcessorToolTargetTuple);
13331
13925
  var toolSubagentFactories = /* @__PURE__ */ new Map([
13332
13926
  [
13333
13927
  "agentsmd",
@@ -13419,6 +14013,13 @@ var toolSubagentFactories = /* @__PURE__ */ new Map([
13419
14013
  class: RooSubagent,
13420
14014
  meta: { supportsSimulated: true, supportsGlobal: false, filePattern: "*.md" }
13421
14015
  }
14016
+ ],
14017
+ [
14018
+ "rovodev",
14019
+ {
14020
+ class: RovodevSubagent,
14021
+ meta: { supportsSimulated: false, supportsGlobal: true, filePattern: "*.md" }
14022
+ }
13422
14023
  ]
13423
14024
  ]);
13424
14025
  var defaultGetFactory5 = (target) => {
@@ -13504,7 +14105,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
13504
14105
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
13505
14106
  */
13506
14107
  async loadRulesyncFiles() {
13507
- const subagentsDir = join96(process.cwd(), RulesyncSubagent.getSettablePaths().relativeDirPath);
14108
+ const subagentsDir = join99(process.cwd(), RulesyncSubagent.getSettablePaths().relativeDirPath);
13508
14109
  const dirExists = await directoryExists(subagentsDir);
13509
14110
  if (!dirExists) {
13510
14111
  this.logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -13519,7 +14120,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
13519
14120
  this.logger.debug(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
13520
14121
  const rulesyncSubagents = [];
13521
14122
  for (const mdFile of mdFiles) {
13522
- const filepath = join96(subagentsDir, mdFile);
14123
+ const filepath = join99(subagentsDir, mdFile);
13523
14124
  try {
13524
14125
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
13525
14126
  relativeFilePath: mdFile,
@@ -13549,7 +14150,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
13549
14150
  const factory = this.getFactory(this.toolTarget);
13550
14151
  const paths = factory.class.getSettablePaths({ global: this.global });
13551
14152
  const subagentFilePaths = await findFilesByGlobs(
13552
- join96(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
14153
+ join99(this.baseDir, paths.relativeDirPath, factory.meta.filePattern)
13553
14154
  );
13554
14155
  if (forDeletion) {
13555
14156
  const toolSubagents2 = subagentFilePaths.map(
@@ -13616,49 +14217,49 @@ var SubagentsProcessor = class extends FeatureProcessor {
13616
14217
  };
13617
14218
 
13618
14219
  // src/features/rules/agentsmd-rule.ts
13619
- import { join as join99 } from "path";
14220
+ import { join as join102 } from "path";
13620
14221
 
13621
14222
  // src/features/rules/tool-rule.ts
13622
- import { join as join98 } from "path";
14223
+ import { join as join101 } from "path";
13623
14224
 
13624
14225
  // src/features/rules/rulesync-rule.ts
13625
- import { join as join97 } from "path";
13626
- import { z as z53 } from "zod/mini";
13627
- var RulesyncRuleFrontmatterSchema = z53.object({
13628
- root: z53.optional(z53.boolean()),
13629
- localRoot: z53.optional(z53.boolean()),
13630
- targets: z53._default(RulesyncTargetsSchema, ["*"]),
13631
- description: z53.optional(z53.string()),
13632
- globs: z53.optional(z53.array(z53.string())),
13633
- agentsmd: z53.optional(
13634
- z53.object({
14226
+ import { join as join100 } from "path";
14227
+ import { z as z55 } from "zod/mini";
14228
+ var RulesyncRuleFrontmatterSchema = z55.object({
14229
+ root: z55.optional(z55.boolean()),
14230
+ localRoot: z55.optional(z55.boolean()),
14231
+ targets: z55._default(RulesyncTargetsSchema, ["*"]),
14232
+ description: z55.optional(z55.string()),
14233
+ globs: z55.optional(z55.array(z55.string())),
14234
+ agentsmd: z55.optional(
14235
+ z55.looseObject({
13635
14236
  // @example "path/to/subproject"
13636
- subprojectPath: z53.optional(z53.string())
14237
+ subprojectPath: z55.optional(z55.string())
13637
14238
  })
13638
14239
  ),
13639
- claudecode: z53.optional(
13640
- z53.object({
14240
+ claudecode: z55.optional(
14241
+ z55.looseObject({
13641
14242
  // Glob patterns for conditional rules (takes precedence over globs)
13642
14243
  // @example ["src/**/*.ts", "tests/**/*.test.ts"]
13643
- paths: z53.optional(z53.array(z53.string()))
14244
+ paths: z55.optional(z55.array(z55.string()))
13644
14245
  })
13645
14246
  ),
13646
- cursor: z53.optional(
13647
- z53.object({
13648
- alwaysApply: z53.optional(z53.boolean()),
13649
- description: z53.optional(z53.string()),
13650
- globs: z53.optional(z53.array(z53.string()))
14247
+ cursor: z55.optional(
14248
+ z55.looseObject({
14249
+ alwaysApply: z55.optional(z55.boolean()),
14250
+ description: z55.optional(z55.string()),
14251
+ globs: z55.optional(z55.array(z55.string()))
13651
14252
  })
13652
14253
  ),
13653
- copilot: z53.optional(
13654
- z53.object({
13655
- excludeAgent: z53.optional(z53.union([z53.literal("code-review"), z53.literal("coding-agent")]))
14254
+ copilot: z55.optional(
14255
+ z55.looseObject({
14256
+ excludeAgent: z55.optional(z55.union([z55.literal("code-review"), z55.literal("coding-agent")]))
13656
14257
  })
13657
14258
  ),
13658
- antigravity: z53.optional(
13659
- z53.looseObject({
13660
- trigger: z53.optional(z53.string()),
13661
- globs: z53.optional(z53.array(z53.string()))
14259
+ antigravity: z55.optional(
14260
+ z55.looseObject({
14261
+ trigger: z55.optional(z55.string()),
14262
+ globs: z55.optional(z55.array(z55.string()))
13662
14263
  })
13663
14264
  )
13664
14265
  });
@@ -13669,7 +14270,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
13669
14270
  const parseResult = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
13670
14271
  if (!parseResult.success && rest.validate !== false) {
13671
14272
  throw new Error(
13672
- `Invalid frontmatter in ${join97(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
14273
+ `Invalid frontmatter in ${join100(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`
13673
14274
  );
13674
14275
  }
13675
14276
  const parsedFrontmatter = parseResult.success ? parseResult.data : { ...frontmatter, targets: frontmatter.targets ?? ["*"] };
@@ -13704,7 +14305,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
13704
14305
  return {
13705
14306
  success: false,
13706
14307
  error: new Error(
13707
- `Invalid frontmatter in ${join97(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
14308
+ `Invalid frontmatter in ${join100(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
13708
14309
  )
13709
14310
  };
13710
14311
  }
@@ -13713,7 +14314,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
13713
14314
  relativeFilePath,
13714
14315
  validate = true
13715
14316
  }) {
13716
- const filePath = join97(
14317
+ const filePath = join100(
13717
14318
  process.cwd(),
13718
14319
  this.getSettablePaths().recommended.relativeDirPath,
13719
14320
  relativeFilePath
@@ -13725,16 +14326,10 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
13725
14326
  throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
13726
14327
  }
13727
14328
  const validatedFrontmatter = {
14329
+ ...result.data,
13728
14330
  root: result.data.root ?? false,
13729
14331
  localRoot: result.data.localRoot ?? false,
13730
- targets: result.data.targets ?? ["*"],
13731
- description: result.data.description,
13732
- globs: result.data.globs ?? [],
13733
- agentsmd: result.data.agentsmd,
13734
- claudecode: result.data.claudecode,
13735
- cursor: result.data.cursor,
13736
- copilot: result.data.copilot,
13737
- antigravity: result.data.antigravity
14332
+ globs: result.data.globs ?? []
13738
14333
  };
13739
14334
  return new _RulesyncRule({
13740
14335
  baseDir: process.cwd(),
@@ -13818,7 +14413,7 @@ var ToolRule = class extends ToolFile {
13818
14413
  rulesyncRule,
13819
14414
  validate = true,
13820
14415
  rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
13821
- nonRootPath = { relativeDirPath: join98(".agents", "memories") }
14416
+ nonRootPath = { relativeDirPath: join101(".agents", "memories") }
13822
14417
  }) {
13823
14418
  const params = this.buildToolRuleParamsDefault({
13824
14419
  baseDir,
@@ -13829,7 +14424,7 @@ var ToolRule = class extends ToolFile {
13829
14424
  });
13830
14425
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
13831
14426
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
13832
- params.relativeDirPath = join98(rulesyncFrontmatter.agentsmd.subprojectPath);
14427
+ params.relativeDirPath = join101(rulesyncFrontmatter.agentsmd.subprojectPath);
13833
14428
  params.relativeFilePath = "AGENTS.md";
13834
14429
  }
13835
14430
  return params;
@@ -13878,7 +14473,7 @@ var ToolRule = class extends ToolFile {
13878
14473
  }
13879
14474
  };
13880
14475
  function buildToolPath(toolDir, subDir, excludeToolDir) {
13881
- return excludeToolDir ? subDir : join98(toolDir, subDir);
14476
+ return excludeToolDir ? subDir : join101(toolDir, subDir);
13882
14477
  }
13883
14478
 
13884
14479
  // src/features/rules/agentsmd-rule.ts
@@ -13907,8 +14502,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
13907
14502
  validate = true
13908
14503
  }) {
13909
14504
  const isRoot = relativeFilePath === "AGENTS.md";
13910
- const relativePath = isRoot ? "AGENTS.md" : join99(".agents", "memories", relativeFilePath);
13911
- const fileContent = await readFileContent(join99(baseDir, relativePath));
14505
+ const relativePath = isRoot ? "AGENTS.md" : join102(".agents", "memories", relativeFilePath);
14506
+ const fileContent = await readFileContent(join102(baseDir, relativePath));
13912
14507
  return new _AgentsMdRule({
13913
14508
  baseDir,
13914
14509
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -13963,21 +14558,21 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
13963
14558
  };
13964
14559
 
13965
14560
  // src/features/rules/antigravity-rule.ts
13966
- import { join as join100 } from "path";
13967
- import { z as z54 } from "zod/mini";
13968
- var AntigravityRuleFrontmatterSchema = z54.looseObject({
13969
- trigger: z54.optional(
13970
- z54.union([
13971
- z54.literal("always_on"),
13972
- z54.literal("glob"),
13973
- z54.literal("manual"),
13974
- z54.literal("model_decision"),
13975
- z54.string()
14561
+ import { join as join103 } from "path";
14562
+ import { z as z56 } from "zod/mini";
14563
+ var AntigravityRuleFrontmatterSchema = z56.looseObject({
14564
+ trigger: z56.optional(
14565
+ z56.union([
14566
+ z56.literal("always_on"),
14567
+ z56.literal("glob"),
14568
+ z56.literal("manual"),
14569
+ z56.literal("model_decision"),
14570
+ z56.string()
13976
14571
  // accepts any string for forward compatibility
13977
14572
  ])
13978
14573
  ),
13979
- globs: z54.optional(z54.string()),
13980
- description: z54.optional(z54.string())
14574
+ globs: z56.optional(z56.string()),
14575
+ description: z56.optional(z56.string())
13981
14576
  });
13982
14577
  function parseGlobsString(globs) {
13983
14578
  if (!globs) {
@@ -14122,7 +14717,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
14122
14717
  const result = AntigravityRuleFrontmatterSchema.safeParse(frontmatter);
14123
14718
  if (!result.success) {
14124
14719
  throw new Error(
14125
- `Invalid frontmatter in ${join100(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
14720
+ `Invalid frontmatter in ${join103(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
14126
14721
  );
14127
14722
  }
14128
14723
  }
@@ -14146,7 +14741,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
14146
14741
  relativeFilePath,
14147
14742
  validate = true
14148
14743
  }) {
14149
- const filePath = join100(
14744
+ const filePath = join103(
14150
14745
  baseDir,
14151
14746
  this.getSettablePaths().nonRoot.relativeDirPath,
14152
14747
  relativeFilePath
@@ -14286,7 +14881,7 @@ var AntigravityRule = class _AntigravityRule extends ToolRule {
14286
14881
  };
14287
14882
 
14288
14883
  // src/features/rules/augmentcode-legacy-rule.ts
14289
- import { join as join101 } from "path";
14884
+ import { join as join104 } from "path";
14290
14885
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
14291
14886
  toRulesyncRule() {
14292
14887
  const rulesyncFrontmatter = {
@@ -14346,8 +14941,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
14346
14941
  }) {
14347
14942
  const settablePaths = this.getSettablePaths();
14348
14943
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
14349
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : join101(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
14350
- const fileContent = await readFileContent(join101(baseDir, relativePath));
14944
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : join104(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
14945
+ const fileContent = await readFileContent(join104(baseDir, relativePath));
14351
14946
  return new _AugmentcodeLegacyRule({
14352
14947
  baseDir,
14353
14948
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -14376,7 +14971,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
14376
14971
  };
14377
14972
 
14378
14973
  // src/features/rules/augmentcode-rule.ts
14379
- import { join as join102 } from "path";
14974
+ import { join as join105 } from "path";
14380
14975
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
14381
14976
  toRulesyncRule() {
14382
14977
  return this.toRulesyncRuleDefault();
@@ -14407,7 +15002,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
14407
15002
  relativeFilePath,
14408
15003
  validate = true
14409
15004
  }) {
14410
- const filePath = join102(
15005
+ const filePath = join105(
14411
15006
  baseDir,
14412
15007
  this.getSettablePaths().nonRoot.relativeDirPath,
14413
15008
  relativeFilePath
@@ -14447,7 +15042,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
14447
15042
  };
14448
15043
 
14449
15044
  // src/features/rules/claudecode-legacy-rule.ts
14450
- import { join as join103 } from "path";
15045
+ import { join as join106 } from "path";
14451
15046
  var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
14452
15047
  static getSettablePaths({
14453
15048
  global,
@@ -14489,7 +15084,7 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
14489
15084
  if (isRoot) {
14490
15085
  const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
14491
15086
  const fileContent2 = await readFileContent(
14492
- join103(baseDir, rootDirPath, paths.root.relativeFilePath)
15087
+ join106(baseDir, rootDirPath, paths.root.relativeFilePath)
14493
15088
  );
14494
15089
  return new _ClaudecodeLegacyRule({
14495
15090
  baseDir,
@@ -14503,8 +15098,8 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
14503
15098
  if (!paths.nonRoot) {
14504
15099
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
14505
15100
  }
14506
- const relativePath = join103(paths.nonRoot.relativeDirPath, relativeFilePath);
14507
- const fileContent = await readFileContent(join103(baseDir, relativePath));
15101
+ const relativePath = join106(paths.nonRoot.relativeDirPath, relativeFilePath);
15102
+ const fileContent = await readFileContent(join106(baseDir, relativePath));
14508
15103
  return new _ClaudecodeLegacyRule({
14509
15104
  baseDir,
14510
15105
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -14563,10 +15158,10 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
14563
15158
  };
14564
15159
 
14565
15160
  // src/features/rules/claudecode-rule.ts
14566
- import { join as join104 } from "path";
14567
- import { z as z55 } from "zod/mini";
14568
- var ClaudecodeRuleFrontmatterSchema = z55.object({
14569
- paths: z55.optional(z55.array(z55.string()))
15161
+ import { join as join107 } from "path";
15162
+ import { z as z57 } from "zod/mini";
15163
+ var ClaudecodeRuleFrontmatterSchema = z57.object({
15164
+ paths: z57.optional(z57.array(z57.string()))
14570
15165
  });
14571
15166
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14572
15167
  frontmatter;
@@ -14604,7 +15199,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14604
15199
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
14605
15200
  if (!result.success) {
14606
15201
  throw new Error(
14607
- `Invalid frontmatter in ${join104(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
15202
+ `Invalid frontmatter in ${join107(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
14608
15203
  );
14609
15204
  }
14610
15205
  }
@@ -14634,7 +15229,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14634
15229
  if (isRoot) {
14635
15230
  const rootDirPath = overrideDirPath ?? paths.root.relativeDirPath;
14636
15231
  const fileContent2 = await readFileContent(
14637
- join104(baseDir, rootDirPath, paths.root.relativeFilePath)
15232
+ join107(baseDir, rootDirPath, paths.root.relativeFilePath)
14638
15233
  );
14639
15234
  return new _ClaudecodeRule({
14640
15235
  baseDir,
@@ -14649,8 +15244,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14649
15244
  if (!paths.nonRoot) {
14650
15245
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
14651
15246
  }
14652
- const relativePath = join104(paths.nonRoot.relativeDirPath, relativeFilePath);
14653
- const filePath = join104(baseDir, relativePath);
15247
+ const relativePath = join107(paths.nonRoot.relativeDirPath, relativeFilePath);
15248
+ const filePath = join107(baseDir, relativePath);
14654
15249
  const fileContent = await readFileContent(filePath);
14655
15250
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
14656
15251
  const result = ClaudecodeRuleFrontmatterSchema.safeParse(frontmatter);
@@ -14761,7 +15356,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14761
15356
  return {
14762
15357
  success: false,
14763
15358
  error: new Error(
14764
- `Invalid frontmatter in ${join104(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
15359
+ `Invalid frontmatter in ${join107(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
14765
15360
  )
14766
15361
  };
14767
15362
  }
@@ -14781,10 +15376,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
14781
15376
  };
14782
15377
 
14783
15378
  // src/features/rules/cline-rule.ts
14784
- import { join as join105 } from "path";
14785
- import { z as z56 } from "zod/mini";
14786
- var ClineRuleFrontmatterSchema = z56.object({
14787
- description: z56.string()
15379
+ import { join as join108 } from "path";
15380
+ import { z as z58 } from "zod/mini";
15381
+ var ClineRuleFrontmatterSchema = z58.object({
15382
+ description: z58.string()
14788
15383
  });
14789
15384
  var ClineRule = class _ClineRule extends ToolRule {
14790
15385
  static getSettablePaths(_options = {}) {
@@ -14827,7 +15422,7 @@ var ClineRule = class _ClineRule extends ToolRule {
14827
15422
  validate = true
14828
15423
  }) {
14829
15424
  const fileContent = await readFileContent(
14830
- join105(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
15425
+ join108(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
14831
15426
  );
14832
15427
  return new _ClineRule({
14833
15428
  baseDir,
@@ -14853,7 +15448,7 @@ var ClineRule = class _ClineRule extends ToolRule {
14853
15448
  };
14854
15449
 
14855
15450
  // src/features/rules/codexcli-rule.ts
14856
- import { join as join106 } from "path";
15451
+ import { join as join109 } from "path";
14857
15452
  var CodexcliRule = class _CodexcliRule extends ToolRule {
14858
15453
  static getSettablePaths({
14859
15454
  global,
@@ -14888,7 +15483,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
14888
15483
  if (isRoot) {
14889
15484
  const relativePath2 = paths.root.relativeFilePath;
14890
15485
  const fileContent2 = await readFileContent(
14891
- join106(baseDir, paths.root.relativeDirPath, relativePath2)
15486
+ join109(baseDir, paths.root.relativeDirPath, relativePath2)
14892
15487
  );
14893
15488
  return new _CodexcliRule({
14894
15489
  baseDir,
@@ -14902,8 +15497,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
14902
15497
  if (!paths.nonRoot) {
14903
15498
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
14904
15499
  }
14905
- const relativePath = join106(paths.nonRoot.relativeDirPath, relativeFilePath);
14906
- const fileContent = await readFileContent(join106(baseDir, relativePath));
15500
+ const relativePath = join109(paths.nonRoot.relativeDirPath, relativeFilePath);
15501
+ const fileContent = await readFileContent(join109(baseDir, relativePath));
14907
15502
  return new _CodexcliRule({
14908
15503
  baseDir,
14909
15504
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -14962,12 +15557,12 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
14962
15557
  };
14963
15558
 
14964
15559
  // src/features/rules/copilot-rule.ts
14965
- import { join as join107 } from "path";
14966
- import { z as z57 } from "zod/mini";
14967
- var CopilotRuleFrontmatterSchema = z57.object({
14968
- description: z57.optional(z57.string()),
14969
- applyTo: z57.optional(z57.string()),
14970
- excludeAgent: z57.optional(z57.union([z57.literal("code-review"), z57.literal("coding-agent")]))
15560
+ import { join as join110 } from "path";
15561
+ import { z as z59 } from "zod/mini";
15562
+ var CopilotRuleFrontmatterSchema = z59.object({
15563
+ description: z59.optional(z59.string()),
15564
+ applyTo: z59.optional(z59.string()),
15565
+ excludeAgent: z59.optional(z59.union([z59.literal("code-review"), z59.literal("coding-agent")]))
14971
15566
  });
14972
15567
  var CopilotRule = class _CopilotRule extends ToolRule {
14973
15568
  frontmatter;
@@ -14999,7 +15594,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
14999
15594
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
15000
15595
  if (!result.success) {
15001
15596
  throw new Error(
15002
- `Invalid frontmatter in ${join107(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
15597
+ `Invalid frontmatter in ${join110(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
15003
15598
  );
15004
15599
  }
15005
15600
  }
@@ -15089,8 +15684,8 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15089
15684
  const paths = this.getSettablePaths({ global });
15090
15685
  const isRoot = relativeFilePath === paths.root.relativeFilePath;
15091
15686
  if (isRoot) {
15092
- const relativePath2 = join107(paths.root.relativeDirPath, paths.root.relativeFilePath);
15093
- const filePath2 = join107(baseDir, relativePath2);
15687
+ const relativePath2 = join110(paths.root.relativeDirPath, paths.root.relativeFilePath);
15688
+ const filePath2 = join110(baseDir, relativePath2);
15094
15689
  const fileContent2 = await readFileContent(filePath2);
15095
15690
  return new _CopilotRule({
15096
15691
  baseDir,
@@ -15105,8 +15700,8 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15105
15700
  if (!paths.nonRoot) {
15106
15701
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
15107
15702
  }
15108
- const relativePath = join107(paths.nonRoot.relativeDirPath, relativeFilePath);
15109
- const filePath = join107(baseDir, relativePath);
15703
+ const relativePath = join110(paths.nonRoot.relativeDirPath, relativeFilePath);
15704
+ const filePath = join110(baseDir, relativePath);
15110
15705
  const fileContent = await readFileContent(filePath);
15111
15706
  const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
15112
15707
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
@@ -15152,7 +15747,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15152
15747
  return {
15153
15748
  success: false,
15154
15749
  error: new Error(
15155
- `Invalid frontmatter in ${join107(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
15750
+ `Invalid frontmatter in ${join110(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
15156
15751
  )
15157
15752
  };
15158
15753
  }
@@ -15172,12 +15767,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15172
15767
  };
15173
15768
 
15174
15769
  // src/features/rules/cursor-rule.ts
15175
- import { join as join108 } from "path";
15176
- import { z as z58 } from "zod/mini";
15177
- var CursorRuleFrontmatterSchema = z58.object({
15178
- description: z58.optional(z58.string()),
15179
- globs: z58.optional(z58.string()),
15180
- alwaysApply: z58.optional(z58.boolean())
15770
+ import { join as join111 } from "path";
15771
+ import { z as z60 } from "zod/mini";
15772
+ var CursorRuleFrontmatterSchema = z60.object({
15773
+ description: z60.optional(z60.string()),
15774
+ globs: z60.optional(z60.string()),
15775
+ alwaysApply: z60.optional(z60.boolean())
15181
15776
  });
15182
15777
  var CursorRule = class _CursorRule extends ToolRule {
15183
15778
  frontmatter;
@@ -15194,7 +15789,7 @@ var CursorRule = class _CursorRule extends ToolRule {
15194
15789
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
15195
15790
  if (!result.success) {
15196
15791
  throw new Error(
15197
- `Invalid frontmatter in ${join108(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
15792
+ `Invalid frontmatter in ${join111(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
15198
15793
  );
15199
15794
  }
15200
15795
  }
@@ -15310,7 +15905,7 @@ var CursorRule = class _CursorRule extends ToolRule {
15310
15905
  relativeFilePath,
15311
15906
  validate = true
15312
15907
  }) {
15313
- const filePath = join108(
15908
+ const filePath = join111(
15314
15909
  baseDir,
15315
15910
  this.getSettablePaths().nonRoot.relativeDirPath,
15316
15911
  relativeFilePath
@@ -15320,7 +15915,7 @@ var CursorRule = class _CursorRule extends ToolRule {
15320
15915
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
15321
15916
  if (!result.success) {
15322
15917
  throw new Error(
15323
- `Invalid frontmatter in ${join108(baseDir, relativeFilePath)}: ${formatError(result.error)}`
15918
+ `Invalid frontmatter in ${join111(baseDir, relativeFilePath)}: ${formatError(result.error)}`
15324
15919
  );
15325
15920
  }
15326
15921
  return new _CursorRule({
@@ -15357,7 +15952,7 @@ var CursorRule = class _CursorRule extends ToolRule {
15357
15952
  return {
15358
15953
  success: false,
15359
15954
  error: new Error(
15360
- `Invalid frontmatter in ${join108(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
15955
+ `Invalid frontmatter in ${join111(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
15361
15956
  )
15362
15957
  };
15363
15958
  }
@@ -15377,7 +15972,7 @@ var CursorRule = class _CursorRule extends ToolRule {
15377
15972
  };
15378
15973
 
15379
15974
  // src/features/rules/deepagents-rule.ts
15380
- import { join as join109 } from "path";
15975
+ import { join as join112 } from "path";
15381
15976
  var DeepagentsRule = class _DeepagentsRule extends ToolRule {
15382
15977
  constructor({ fileContent, root, ...rest }) {
15383
15978
  super({
@@ -15403,8 +15998,8 @@ var DeepagentsRule = class _DeepagentsRule extends ToolRule {
15403
15998
  validate = true
15404
15999
  }) {
15405
16000
  const isRoot = relativeFilePath === "AGENTS.md";
15406
- const relativePath = isRoot ? join109(".deepagents", "AGENTS.md") : join109(".deepagents", "memories", relativeFilePath);
15407
- const fileContent = await readFileContent(join109(baseDir, relativePath));
16001
+ const relativePath = isRoot ? join112(".deepagents", "AGENTS.md") : join112(".deepagents", "memories", relativeFilePath);
16002
+ const fileContent = await readFileContent(join112(baseDir, relativePath));
15408
16003
  return new _DeepagentsRule({
15409
16004
  baseDir,
15410
16005
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -15459,7 +16054,7 @@ var DeepagentsRule = class _DeepagentsRule extends ToolRule {
15459
16054
  };
15460
16055
 
15461
16056
  // src/features/rules/factorydroid-rule.ts
15462
- import { join as join110 } from "path";
16057
+ import { join as join113 } from "path";
15463
16058
  var FactorydroidRule = class _FactorydroidRule extends ToolRule {
15464
16059
  constructor({ fileContent, root, ...rest }) {
15465
16060
  super({
@@ -15499,8 +16094,8 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
15499
16094
  const paths = this.getSettablePaths({ global });
15500
16095
  const isRoot = relativeFilePath === paths.root.relativeFilePath;
15501
16096
  if (isRoot) {
15502
- const relativePath2 = join110(paths.root.relativeDirPath, paths.root.relativeFilePath);
15503
- const fileContent2 = await readFileContent(join110(baseDir, relativePath2));
16097
+ const relativePath2 = join113(paths.root.relativeDirPath, paths.root.relativeFilePath);
16098
+ const fileContent2 = await readFileContent(join113(baseDir, relativePath2));
15504
16099
  return new _FactorydroidRule({
15505
16100
  baseDir,
15506
16101
  relativeDirPath: paths.root.relativeDirPath,
@@ -15513,8 +16108,8 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
15513
16108
  if (!paths.nonRoot) {
15514
16109
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
15515
16110
  }
15516
- const relativePath = join110(paths.nonRoot.relativeDirPath, relativeFilePath);
15517
- const fileContent = await readFileContent(join110(baseDir, relativePath));
16111
+ const relativePath = join113(paths.nonRoot.relativeDirPath, relativeFilePath);
16112
+ const fileContent = await readFileContent(join113(baseDir, relativePath));
15518
16113
  return new _FactorydroidRule({
15519
16114
  baseDir,
15520
16115
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -15573,7 +16168,7 @@ var FactorydroidRule = class _FactorydroidRule extends ToolRule {
15573
16168
  };
15574
16169
 
15575
16170
  // src/features/rules/geminicli-rule.ts
15576
- import { join as join111 } from "path";
16171
+ import { join as join114 } from "path";
15577
16172
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
15578
16173
  static getSettablePaths({
15579
16174
  global,
@@ -15608,7 +16203,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
15608
16203
  if (isRoot) {
15609
16204
  const relativePath2 = paths.root.relativeFilePath;
15610
16205
  const fileContent2 = await readFileContent(
15611
- join111(baseDir, paths.root.relativeDirPath, relativePath2)
16206
+ join114(baseDir, paths.root.relativeDirPath, relativePath2)
15612
16207
  );
15613
16208
  return new _GeminiCliRule({
15614
16209
  baseDir,
@@ -15622,8 +16217,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
15622
16217
  if (!paths.nonRoot) {
15623
16218
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
15624
16219
  }
15625
- const relativePath = join111(paths.nonRoot.relativeDirPath, relativeFilePath);
15626
- const fileContent = await readFileContent(join111(baseDir, relativePath));
16220
+ const relativePath = join114(paths.nonRoot.relativeDirPath, relativeFilePath);
16221
+ const fileContent = await readFileContent(join114(baseDir, relativePath));
15627
16222
  return new _GeminiCliRule({
15628
16223
  baseDir,
15629
16224
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -15682,7 +16277,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
15682
16277
  };
15683
16278
 
15684
16279
  // src/features/rules/goose-rule.ts
15685
- import { join as join112 } from "path";
16280
+ import { join as join115 } from "path";
15686
16281
  var GooseRule = class _GooseRule extends ToolRule {
15687
16282
  static getSettablePaths({
15688
16283
  global,
@@ -15717,7 +16312,7 @@ var GooseRule = class _GooseRule extends ToolRule {
15717
16312
  if (isRoot) {
15718
16313
  const relativePath2 = paths.root.relativeFilePath;
15719
16314
  const fileContent2 = await readFileContent(
15720
- join112(baseDir, paths.root.relativeDirPath, relativePath2)
16315
+ join115(baseDir, paths.root.relativeDirPath, relativePath2)
15721
16316
  );
15722
16317
  return new _GooseRule({
15723
16318
  baseDir,
@@ -15731,8 +16326,8 @@ var GooseRule = class _GooseRule extends ToolRule {
15731
16326
  if (!paths.nonRoot) {
15732
16327
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
15733
16328
  }
15734
- const relativePath = join112(paths.nonRoot.relativeDirPath, relativeFilePath);
15735
- const fileContent = await readFileContent(join112(baseDir, relativePath));
16329
+ const relativePath = join115(paths.nonRoot.relativeDirPath, relativeFilePath);
16330
+ const fileContent = await readFileContent(join115(baseDir, relativePath));
15736
16331
  return new _GooseRule({
15737
16332
  baseDir,
15738
16333
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -15791,7 +16386,7 @@ var GooseRule = class _GooseRule extends ToolRule {
15791
16386
  };
15792
16387
 
15793
16388
  // src/features/rules/junie-rule.ts
15794
- import { join as join113 } from "path";
16389
+ import { join as join116 } from "path";
15795
16390
  var JunieRule = class _JunieRule extends ToolRule {
15796
16391
  static getSettablePaths(_options = {}) {
15797
16392
  return {
@@ -15810,8 +16405,8 @@ var JunieRule = class _JunieRule extends ToolRule {
15810
16405
  validate = true
15811
16406
  }) {
15812
16407
  const isRoot = relativeFilePath === "guidelines.md";
15813
- const relativePath = isRoot ? "guidelines.md" : join113(".junie", "memories", relativeFilePath);
15814
- const fileContent = await readFileContent(join113(baseDir, relativePath));
16408
+ const relativePath = isRoot ? "guidelines.md" : join116(".junie", "memories", relativeFilePath);
16409
+ const fileContent = await readFileContent(join116(baseDir, relativePath));
15815
16410
  return new _JunieRule({
15816
16411
  baseDir,
15817
16412
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -15866,7 +16461,7 @@ var JunieRule = class _JunieRule extends ToolRule {
15866
16461
  };
15867
16462
 
15868
16463
  // src/features/rules/kilo-rule.ts
15869
- import { join as join114 } from "path";
16464
+ import { join as join117 } from "path";
15870
16465
  var KiloRule = class _KiloRule extends ToolRule {
15871
16466
  static getSettablePaths(_options = {}) {
15872
16467
  return {
@@ -15881,7 +16476,7 @@ var KiloRule = class _KiloRule extends ToolRule {
15881
16476
  validate = true
15882
16477
  }) {
15883
16478
  const fileContent = await readFileContent(
15884
- join114(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
16479
+ join117(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
15885
16480
  );
15886
16481
  return new _KiloRule({
15887
16482
  baseDir,
@@ -15933,7 +16528,7 @@ var KiloRule = class _KiloRule extends ToolRule {
15933
16528
  };
15934
16529
 
15935
16530
  // src/features/rules/kiro-rule.ts
15936
- import { join as join115 } from "path";
16531
+ import { join as join118 } from "path";
15937
16532
  var KiroRule = class _KiroRule extends ToolRule {
15938
16533
  static getSettablePaths(_options = {}) {
15939
16534
  return {
@@ -15948,7 +16543,7 @@ var KiroRule = class _KiroRule extends ToolRule {
15948
16543
  validate = true
15949
16544
  }) {
15950
16545
  const fileContent = await readFileContent(
15951
- join115(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
16546
+ join118(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
15952
16547
  );
15953
16548
  return new _KiroRule({
15954
16549
  baseDir,
@@ -16002,7 +16597,7 @@ var KiroRule = class _KiroRule extends ToolRule {
16002
16597
  };
16003
16598
 
16004
16599
  // src/features/rules/opencode-rule.ts
16005
- import { join as join116 } from "path";
16600
+ import { join as join119 } from "path";
16006
16601
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
16007
16602
  static getSettablePaths({
16008
16603
  global,
@@ -16037,7 +16632,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
16037
16632
  if (isRoot) {
16038
16633
  const relativePath2 = paths.root.relativeFilePath;
16039
16634
  const fileContent2 = await readFileContent(
16040
- join116(baseDir, paths.root.relativeDirPath, relativePath2)
16635
+ join119(baseDir, paths.root.relativeDirPath, relativePath2)
16041
16636
  );
16042
16637
  return new _OpenCodeRule({
16043
16638
  baseDir,
@@ -16051,8 +16646,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
16051
16646
  if (!paths.nonRoot) {
16052
16647
  throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
16053
16648
  }
16054
- const relativePath = join116(paths.nonRoot.relativeDirPath, relativeFilePath);
16055
- const fileContent = await readFileContent(join116(baseDir, relativePath));
16649
+ const relativePath = join119(paths.nonRoot.relativeDirPath, relativeFilePath);
16650
+ const fileContent = await readFileContent(join119(baseDir, relativePath));
16056
16651
  return new _OpenCodeRule({
16057
16652
  baseDir,
16058
16653
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -16070,7 +16665,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
16070
16665
  }) {
16071
16666
  const paths = this.getSettablePaths({ global });
16072
16667
  return new _OpenCodeRule(
16073
- this.buildToolRuleParamsDefault({
16668
+ this.buildToolRuleParamsAgentsmd({
16074
16669
  baseDir,
16075
16670
  rulesyncRule,
16076
16671
  validate,
@@ -16111,7 +16706,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
16111
16706
  };
16112
16707
 
16113
16708
  // src/features/rules/qwencode-rule.ts
16114
- import { join as join117 } from "path";
16709
+ import { join as join120 } from "path";
16115
16710
  var QwencodeRule = class _QwencodeRule extends ToolRule {
16116
16711
  static getSettablePaths(_options = {}) {
16117
16712
  return {
@@ -16130,8 +16725,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
16130
16725
  validate = true
16131
16726
  }) {
16132
16727
  const isRoot = relativeFilePath === "QWEN.md";
16133
- const relativePath = isRoot ? "QWEN.md" : join117(".qwen", "memories", relativeFilePath);
16134
- const fileContent = await readFileContent(join117(baseDir, relativePath));
16728
+ const relativePath = isRoot ? "QWEN.md" : join120(".qwen", "memories", relativeFilePath);
16729
+ const fileContent = await readFileContent(join120(baseDir, relativePath));
16135
16730
  return new _QwencodeRule({
16136
16731
  baseDir,
16137
16732
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -16183,7 +16778,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
16183
16778
  };
16184
16779
 
16185
16780
  // src/features/rules/replit-rule.ts
16186
- import { join as join118 } from "path";
16781
+ import { join as join121 } from "path";
16187
16782
  var ReplitRule = class _ReplitRule extends ToolRule {
16188
16783
  static getSettablePaths(_options = {}) {
16189
16784
  return {
@@ -16205,7 +16800,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
16205
16800
  }
16206
16801
  const relativePath = paths.root.relativeFilePath;
16207
16802
  const fileContent = await readFileContent(
16208
- join118(baseDir, paths.root.relativeDirPath, relativePath)
16803
+ join121(baseDir, paths.root.relativeDirPath, relativePath)
16209
16804
  );
16210
16805
  return new _ReplitRule({
16211
16806
  baseDir,
@@ -16271,7 +16866,7 @@ var ReplitRule = class _ReplitRule extends ToolRule {
16271
16866
  };
16272
16867
 
16273
16868
  // src/features/rules/roo-rule.ts
16274
- import { join as join119 } from "path";
16869
+ import { join as join122 } from "path";
16275
16870
  var RooRule = class _RooRule extends ToolRule {
16276
16871
  static getSettablePaths(_options = {}) {
16277
16872
  return {
@@ -16286,7 +16881,7 @@ var RooRule = class _RooRule extends ToolRule {
16286
16881
  validate = true
16287
16882
  }) {
16288
16883
  const fileContent = await readFileContent(
16289
- join119(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
16884
+ join122(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
16290
16885
  );
16291
16886
  return new _RooRule({
16292
16887
  baseDir,
@@ -16354,8 +16949,242 @@ var RooRule = class _RooRule extends ToolRule {
16354
16949
  }
16355
16950
  };
16356
16951
 
16952
+ // src/features/rules/rovodev-rule.ts
16953
+ import { join as join123 } from "path";
16954
+ var DISALLOWED_ROVODEV_MODULAR_RULE_BASENAMES = /* @__PURE__ */ new Set(["agents.md", "agents.local.md"]);
16955
+ var RovodevRule = class _RovodevRule extends ToolRule {
16956
+ /**
16957
+ * Whether `relativePath` (posix-style path relative to modular-rules root) may be imported as a modular rule.
16958
+ * Rejects memory filenames that belong at repo root or under `.rovodev/AGENTS.md`.
16959
+ */
16960
+ static isAllowedModularRulesRelativePath(relativePath) {
16961
+ if (!relativePath) {
16962
+ return false;
16963
+ }
16964
+ for (const segment of relativePath.split(/[/\\]/)) {
16965
+ if (segment === "" || segment === "." || segment === "..") {
16966
+ continue;
16967
+ }
16968
+ if (DISALLOWED_ROVODEV_MODULAR_RULE_BASENAMES.has(segment.toLowerCase())) {
16969
+ return false;
16970
+ }
16971
+ }
16972
+ return true;
16973
+ }
16974
+ constructor({ fileContent, root, ...rest }) {
16975
+ super({
16976
+ ...rest,
16977
+ fileContent,
16978
+ root: root ?? false
16979
+ });
16980
+ }
16981
+ static getSettablePaths({
16982
+ global = false
16983
+ } = {}) {
16984
+ const rovodevAgents = {
16985
+ relativeDirPath: ".rovodev",
16986
+ relativeFilePath: "AGENTS.md"
16987
+ };
16988
+ if (global) {
16989
+ return {
16990
+ root: rovodevAgents
16991
+ };
16992
+ }
16993
+ return {
16994
+ root: rovodevAgents,
16995
+ alternativeRoots: [{ relativeDirPath: ".", relativeFilePath: "AGENTS.md" }],
16996
+ nonRoot: {
16997
+ relativeDirPath: join123(".rovodev", ".rulesync", "modular-rules")
16998
+ }
16999
+ };
17000
+ }
17001
+ static async fromFile({
17002
+ baseDir = process.cwd(),
17003
+ relativeFilePath,
17004
+ relativeDirPath: overrideDirPath,
17005
+ validate = true,
17006
+ global = false
17007
+ }) {
17008
+ const paths = this.getSettablePaths({ global });
17009
+ if (!global && "nonRoot" in paths && paths.nonRoot && overrideDirPath === paths.nonRoot.relativeDirPath) {
17010
+ return this.fromModularFile({
17011
+ baseDir,
17012
+ relativeFilePath,
17013
+ relativeDirPath: overrideDirPath,
17014
+ validate,
17015
+ global
17016
+ });
17017
+ }
17018
+ return this.fromRootFile({
17019
+ baseDir,
17020
+ relativeFilePath,
17021
+ overrideDirPath,
17022
+ validate,
17023
+ global,
17024
+ paths
17025
+ });
17026
+ }
17027
+ static async fromModularFile({
17028
+ baseDir,
17029
+ relativeFilePath,
17030
+ relativeDirPath,
17031
+ validate,
17032
+ global
17033
+ }) {
17034
+ if (!this.isAllowedModularRulesRelativePath(relativeFilePath)) {
17035
+ throw new Error(
17036
+ `Reserved Rovodev memory basename under modular-rules (not a modular rule): ${join123(relativeDirPath, relativeFilePath)}`
17037
+ );
17038
+ }
17039
+ const fileContent = await readFileContent(join123(baseDir, relativeDirPath, relativeFilePath));
17040
+ return new _RovodevRule({
17041
+ baseDir,
17042
+ relativeDirPath,
17043
+ relativeFilePath,
17044
+ fileContent,
17045
+ validate,
17046
+ global,
17047
+ root: false
17048
+ });
17049
+ }
17050
+ static async fromRootFile({
17051
+ baseDir,
17052
+ relativeFilePath,
17053
+ overrideDirPath,
17054
+ validate,
17055
+ global,
17056
+ paths
17057
+ }) {
17058
+ const relativeDirPath = overrideDirPath ?? paths.root.relativeDirPath;
17059
+ const agentsMdExpectedLocationsDescription = "alternativeRoots" in paths && paths.alternativeRoots && paths.alternativeRoots.length > 0 ? `${join123(paths.root.relativeDirPath, paths.root.relativeFilePath)} or project root` : join123(paths.root.relativeDirPath, paths.root.relativeFilePath);
17060
+ if (relativeFilePath !== "AGENTS.md") {
17061
+ throw new Error(
17062
+ `Rovodev rules support only AGENTS.md at ${agentsMdExpectedLocationsDescription}, got: ${join123(relativeDirPath, relativeFilePath)}`
17063
+ );
17064
+ }
17065
+ const allowed = relativeDirPath === paths.root.relativeDirPath || "alternativeRoots" in paths && paths.alternativeRoots?.some(
17066
+ (alt) => alt.relativeDirPath === relativeDirPath && alt.relativeFilePath === relativeFilePath
17067
+ );
17068
+ if (!allowed) {
17069
+ throw new Error(
17070
+ `Rovodev AGENTS.md must be at ${agentsMdExpectedLocationsDescription}, got: ${join123(relativeDirPath, relativeFilePath)}`
17071
+ );
17072
+ }
17073
+ const fileContent = await readFileContent(join123(baseDir, relativeDirPath, relativeFilePath));
17074
+ return new _RovodevRule({
17075
+ baseDir,
17076
+ relativeDirPath,
17077
+ relativeFilePath,
17078
+ fileContent,
17079
+ validate,
17080
+ global,
17081
+ root: true
17082
+ });
17083
+ }
17084
+ static forDeletion({
17085
+ baseDir = process.cwd(),
17086
+ relativeDirPath,
17087
+ relativeFilePath,
17088
+ global = false
17089
+ }) {
17090
+ return new _RovodevRule({
17091
+ baseDir,
17092
+ relativeDirPath: relativeDirPath ?? ".",
17093
+ relativeFilePath: relativeFilePath ?? "AGENTS.md",
17094
+ fileContent: "",
17095
+ validate: false,
17096
+ global,
17097
+ root: relativeFilePath === "AGENTS.md"
17098
+ });
17099
+ }
17100
+ static fromRulesyncRule({
17101
+ baseDir = process.cwd(),
17102
+ rulesyncRule,
17103
+ validate = true,
17104
+ global = false
17105
+ }) {
17106
+ const paths = this.getSettablePaths({ global });
17107
+ const isRoot = rulesyncRule.getFrontmatter().root ?? false;
17108
+ if (isRoot) {
17109
+ return new _RovodevRule(
17110
+ this.buildToolRuleParamsDefault({
17111
+ baseDir,
17112
+ rulesyncRule,
17113
+ validate,
17114
+ global,
17115
+ rootPath: paths.root,
17116
+ nonRootPath: void 0
17117
+ })
17118
+ );
17119
+ }
17120
+ if (global || !("nonRoot" in paths) || !paths.nonRoot) {
17121
+ throw new Error(
17122
+ "Rovodev non-root (modular) rules are only supported in project mode with .rovodev/.rulesync/modular-rules."
17123
+ );
17124
+ }
17125
+ const modularRelativePath = rulesyncRule.getRelativeFilePath();
17126
+ if (!this.isAllowedModularRulesRelativePath(modularRelativePath)) {
17127
+ throw new Error(
17128
+ `Reserved Rovodev memory basename in modular rule path: ${modularRelativePath}`
17129
+ );
17130
+ }
17131
+ return new _RovodevRule(
17132
+ this.buildToolRuleParamsDefault({
17133
+ baseDir,
17134
+ rulesyncRule,
17135
+ validate,
17136
+ global,
17137
+ rootPath: paths.root,
17138
+ nonRootPath: paths.nonRoot
17139
+ })
17140
+ );
17141
+ }
17142
+ toRulesyncRule() {
17143
+ if (this.getRelativeFilePath() === "AGENTS.local.md") {
17144
+ return new RulesyncRule({
17145
+ baseDir: this.getBaseDir(),
17146
+ relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
17147
+ relativeFilePath: "AGENTS.local.md",
17148
+ frontmatter: {
17149
+ targets: ["rovodev"],
17150
+ root: false,
17151
+ localRoot: true,
17152
+ globs: []
17153
+ },
17154
+ body: this.getFileContent(),
17155
+ validate: true
17156
+ });
17157
+ }
17158
+ if (!this.isRoot()) {
17159
+ return new RulesyncRule({
17160
+ baseDir: this.getBaseDir(),
17161
+ relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
17162
+ relativeFilePath: this.getRelativeFilePath(),
17163
+ frontmatter: {
17164
+ targets: ["rovodev"],
17165
+ root: false,
17166
+ globs: this.globs ?? [],
17167
+ ...this.description !== void 0 ? { description: this.description } : {}
17168
+ },
17169
+ body: this.getFileContent(),
17170
+ validate: true
17171
+ });
17172
+ }
17173
+ return this.toRulesyncRuleDefault();
17174
+ }
17175
+ validate() {
17176
+ return { success: true, error: null };
17177
+ }
17178
+ static isTargetedByRulesyncRule(rulesyncRule) {
17179
+ return this.isTargetedByRulesyncRuleDefault({
17180
+ rulesyncRule,
17181
+ toolTarget: "rovodev"
17182
+ });
17183
+ }
17184
+ };
17185
+
16357
17186
  // src/features/rules/warp-rule.ts
16358
- import { join as join120 } from "path";
17187
+ import { join as join124 } from "path";
16359
17188
  var WarpRule = class _WarpRule extends ToolRule {
16360
17189
  constructor({ fileContent, root, ...rest }) {
16361
17190
  super({
@@ -16381,8 +17210,8 @@ var WarpRule = class _WarpRule extends ToolRule {
16381
17210
  validate = true
16382
17211
  }) {
16383
17212
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
16384
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join120(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
16385
- const fileContent = await readFileContent(join120(baseDir, relativePath));
17213
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join124(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
17214
+ const fileContent = await readFileContent(join124(baseDir, relativePath));
16386
17215
  return new _WarpRule({
16387
17216
  baseDir,
16388
17217
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -16437,7 +17266,7 @@ var WarpRule = class _WarpRule extends ToolRule {
16437
17266
  };
16438
17267
 
16439
17268
  // src/features/rules/windsurf-rule.ts
16440
- import { join as join121 } from "path";
17269
+ import { join as join125 } from "path";
16441
17270
  var WindsurfRule = class _WindsurfRule extends ToolRule {
16442
17271
  static getSettablePaths(_options = {}) {
16443
17272
  return {
@@ -16452,7 +17281,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
16452
17281
  validate = true
16453
17282
  }) {
16454
17283
  const fileContent = await readFileContent(
16455
- join121(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
17284
+ join125(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
16456
17285
  );
16457
17286
  return new _WindsurfRule({
16458
17287
  baseDir,
@@ -16526,11 +17355,12 @@ var rulesProcessorToolTargets = [
16526
17355
  "qwencode",
16527
17356
  "replit",
16528
17357
  "roo",
17358
+ "rovodev",
16529
17359
  "warp",
16530
17360
  "windsurf"
16531
17361
  ];
16532
- var RulesProcessorToolTargetSchema = z59.enum(rulesProcessorToolTargets);
16533
- var formatRulePaths = (rules) => rules.map((r) => join122(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
17362
+ var RulesProcessorToolTargetSchema = z61.enum(rulesProcessorToolTargets);
17363
+ var formatRulePaths = (rules) => rules.map((r) => join126(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
16534
17364
  var toolRuleFactories = /* @__PURE__ */ new Map([
16535
17365
  [
16536
17366
  "agentsmd",
@@ -16780,6 +17610,21 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
16780
17610
  }
16781
17611
  }
16782
17612
  ],
17613
+ [
17614
+ "rovodev",
17615
+ {
17616
+ class: RovodevRule,
17617
+ meta: {
17618
+ extension: "md",
17619
+ supportsGlobal: true,
17620
+ ruleDiscoveryMode: "toon",
17621
+ additionalConventions: {
17622
+ subagents: { subagentClass: RovodevSubagent },
17623
+ skills: { skillClass: RovodevSkill }
17624
+ }
17625
+ }
17626
+ }
17627
+ ],
16783
17628
  [
16784
17629
  "warp",
16785
17630
  {
@@ -16908,6 +17753,21 @@ var RulesProcessor = class extends FeatureProcessor {
16908
17753
  const conventionsSection = !meta.createsSeparateConventionsRule && meta.additionalConventions ? this.generateAdditionalConventionsSectionFromMeta(meta) : "";
16909
17754
  const newContent = referenceSection + conventionsSection + rootRule.getFileContent();
16910
17755
  rootRule.setFileContent(newContent);
17756
+ if (this.toolTarget === "rovodev" && !this.global && rootRule instanceof RovodevRule) {
17757
+ const primary = RovodevRule.getSettablePaths({ global: false }).root;
17758
+ if (rootRule.getRelativeDirPath() === primary.relativeDirPath && rootRule.getRelativeFilePath() === primary.relativeFilePath) {
17759
+ toolRules.push(
17760
+ new RovodevRule({
17761
+ baseDir: this.baseDir,
17762
+ relativeDirPath: ".",
17763
+ relativeFilePath: "AGENTS.md",
17764
+ fileContent: newContent,
17765
+ validate: true,
17766
+ root: true
17767
+ })
17768
+ );
17769
+ }
17770
+ }
16911
17771
  return toolRules;
16912
17772
  }
16913
17773
  buildSkillList(skillClass) {
@@ -16917,7 +17777,7 @@ var RulesProcessor = class extends FeatureProcessor {
16917
17777
  }).relativeDirPath;
16918
17778
  return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
16919
17779
  const frontmatter = skill.getFrontmatter();
16920
- const relativePath = join122(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
17780
+ const relativePath = join126(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
16921
17781
  return {
16922
17782
  name: frontmatter.name,
16923
17783
  description: frontmatter.description,
@@ -16929,6 +17789,7 @@ var RulesProcessor = class extends FeatureProcessor {
16929
17789
  * Handle localRoot rule generation based on tool target.
16930
17790
  * - Claude Code: generates `./CLAUDE.local.md`
16931
17791
  * - Claude Code Legacy: generates `./CLAUDE.local.md`
17792
+ * - Rovodev: generates `./AGENTS.local.md` (Rovo Dev CLI project memory)
16932
17793
  * - Other tools: appends content to the root file with one blank line separator
16933
17794
  */
16934
17795
  handleLocalRootRule(toolRules, localRootRule, _factory) {
@@ -16962,6 +17823,17 @@ var RulesProcessor = class extends FeatureProcessor {
16962
17823
  // Treat as root so it doesn't have frontmatter
16963
17824
  })
16964
17825
  );
17826
+ } else if (this.toolTarget === "rovodev") {
17827
+ toolRules.push(
17828
+ new RovodevRule({
17829
+ baseDir: this.baseDir,
17830
+ relativeDirPath: ".",
17831
+ relativeFilePath: "AGENTS.local.md",
17832
+ fileContent: localRootBody,
17833
+ validate: true,
17834
+ root: true
17835
+ })
17836
+ );
16965
17837
  } else {
16966
17838
  const rootRule = toolRules.find((rule) => rule.isRoot());
16967
17839
  if (rootRule) {
@@ -17030,8 +17902,8 @@ var RulesProcessor = class extends FeatureProcessor {
17030
17902
  * Load and parse rulesync rule files from .rulesync/rules/ directory
17031
17903
  */
17032
17904
  async loadRulesyncFiles() {
17033
- const rulesyncBaseDir = join122(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
17034
- const files = await findFilesByGlobs(join122(rulesyncBaseDir, "**", "*.md"));
17905
+ const rulesyncBaseDir = join126(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
17906
+ const files = await findFilesByGlobs(join126(rulesyncBaseDir, "**", "*.md"));
17035
17907
  this.logger.debug(`Found ${files.length} rulesync files`);
17036
17908
  const rulesyncRules = await Promise.all(
17037
17909
  files.map((file) => {
@@ -17113,6 +17985,24 @@ var RulesProcessor = class extends FeatureProcessor {
17113
17985
  const dirName = dirname3(relative5(this.baseDir, filePath));
17114
17986
  return dirName === "" ? "." : dirName;
17115
17987
  };
17988
+ const buildDeletionRulesFromPaths = (filePaths, opts) => {
17989
+ const isNonRoot = opts !== void 0;
17990
+ const effectiveBaseDir = isNonRoot ? opts.baseDirOverride : this.baseDir;
17991
+ return filePaths.map((filePath) => {
17992
+ const relativeDirPath = isNonRoot ? opts.relativeDirPathOverride : resolveRelativeDirPath(filePath);
17993
+ const relativeFilePath = isNonRoot ? relative5(effectiveBaseDir, filePath) : basename10(filePath);
17994
+ checkPathTraversal({
17995
+ relativePath: isNonRoot ? relativeFilePath : relativeDirPath,
17996
+ intendedRootDir: effectiveBaseDir
17997
+ });
17998
+ return factory.class.forDeletion({
17999
+ baseDir: this.baseDir,
18000
+ relativeDirPath,
18001
+ relativeFilePath,
18002
+ global: this.global
18003
+ });
18004
+ }).filter((rule) => rule.isDeletable());
18005
+ };
17116
18006
  const findFilesWithFallback = async (primaryGlob, alternativeRoots, buildAltGlob) => {
17117
18007
  const primaryFilePaths = await findFilesByGlobs(primaryGlob);
17118
18008
  if (primaryFilePaths.length > 0) {
@@ -17128,28 +18018,16 @@ var RulesProcessor = class extends FeatureProcessor {
17128
18018
  return [];
17129
18019
  }
17130
18020
  const uniqueRootFilePaths = await findFilesWithFallback(
17131
- join122(
18021
+ join126(
17132
18022
  this.baseDir,
17133
18023
  settablePaths.root.relativeDirPath ?? ".",
17134
18024
  settablePaths.root.relativeFilePath
17135
18025
  ),
17136
18026
  settablePaths.alternativeRoots,
17137
- (alt) => join122(this.baseDir, alt.relativeDirPath, alt.relativeFilePath)
18027
+ (alt) => join126(this.baseDir, alt.relativeDirPath, alt.relativeFilePath)
17138
18028
  );
17139
18029
  if (forDeletion) {
17140
- return uniqueRootFilePaths.map((filePath) => {
17141
- const relativeDirPath = resolveRelativeDirPath(filePath);
17142
- checkPathTraversal({
17143
- relativePath: relativeDirPath,
17144
- intendedRootDir: this.baseDir
17145
- });
17146
- return factory.class.forDeletion({
17147
- baseDir: this.baseDir,
17148
- relativeDirPath,
17149
- relativeFilePath: basename10(filePath),
17150
- global: this.global
17151
- });
17152
- }).filter((rule) => rule.isDeletable());
18030
+ return buildDeletionRulesFromPaths(uniqueRootFilePaths);
17153
18031
  }
17154
18032
  return await Promise.all(
17155
18033
  uniqueRootFilePaths.map((filePath) => {
@@ -17172,6 +18050,15 @@ var RulesProcessor = class extends FeatureProcessor {
17172
18050
  if (!forDeletion) {
17173
18051
  return [];
17174
18052
  }
18053
+ if (this.toolTarget === "rovodev") {
18054
+ if (this.global) {
18055
+ return [];
18056
+ }
18057
+ const uniqueLocalRootFilePaths2 = await findFilesByGlobs(
18058
+ join126(this.baseDir, "AGENTS.local.md")
18059
+ );
18060
+ return buildDeletionRulesFromPaths(uniqueLocalRootFilePaths2);
18061
+ }
17175
18062
  if (this.toolTarget !== "claudecode" && this.toolTarget !== "claudecode-legacy") {
17176
18063
  return [];
17177
18064
  }
@@ -17179,52 +18066,53 @@ var RulesProcessor = class extends FeatureProcessor {
17179
18066
  return [];
17180
18067
  }
17181
18068
  const uniqueLocalRootFilePaths = await findFilesWithFallback(
17182
- join122(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md"),
18069
+ join126(this.baseDir, settablePaths.root.relativeDirPath ?? ".", "CLAUDE.local.md"),
17183
18070
  settablePaths.alternativeRoots,
17184
- (alt) => join122(this.baseDir, alt.relativeDirPath, "CLAUDE.local.md")
18071
+ (alt) => join126(this.baseDir, alt.relativeDirPath, "CLAUDE.local.md")
17185
18072
  );
17186
- return uniqueLocalRootFilePaths.map((filePath) => {
17187
- const relativeDirPath = resolveRelativeDirPath(filePath);
17188
- checkPathTraversal({
17189
- relativePath: relativeDirPath,
17190
- intendedRootDir: this.baseDir
17191
- });
17192
- return factory.class.forDeletion({
17193
- baseDir: this.baseDir,
17194
- relativeDirPath,
17195
- relativeFilePath: basename10(filePath),
17196
- global: this.global
17197
- });
17198
- }).filter((rule) => rule.isDeletable());
18073
+ return buildDeletionRulesFromPaths(uniqueLocalRootFilePaths);
17199
18074
  })();
17200
18075
  this.logger.debug(
17201
18076
  `Found ${localRootToolRules.length} local root tool rule files for deletion`
17202
18077
  );
18078
+ const rovodevMirrorDeletionRules = await (async () => {
18079
+ if (!forDeletion || this.toolTarget !== "rovodev" || this.global) {
18080
+ return [];
18081
+ }
18082
+ const primaryPaths = await findFilesByGlobs(join126(this.baseDir, ".rovodev", "AGENTS.md"));
18083
+ if (primaryPaths.length === 0) {
18084
+ return [];
18085
+ }
18086
+ const mirrorPaths = await findFilesByGlobs(join126(this.baseDir, "AGENTS.md"));
18087
+ return buildDeletionRulesFromPaths(mirrorPaths);
18088
+ })();
17203
18089
  const nonRootToolRules = await (async () => {
17204
18090
  if (!settablePaths.nonRoot) {
17205
18091
  return [];
17206
18092
  }
17207
- const nonRootBaseDir = join122(this.baseDir, settablePaths.nonRoot.relativeDirPath);
18093
+ const nonRootBaseDir = join126(this.baseDir, settablePaths.nonRoot.relativeDirPath);
17208
18094
  const nonRootFilePaths = await findFilesByGlobs(
17209
- join122(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
18095
+ join126(nonRootBaseDir, "**", `*.${factory.meta.extension}`)
17210
18096
  );
17211
18097
  if (forDeletion) {
17212
- return nonRootFilePaths.map((filePath) => {
17213
- const relativeFilePath = relative5(nonRootBaseDir, filePath);
17214
- checkPathTraversal({
17215
- relativePath: relativeFilePath,
17216
- intendedRootDir: nonRootBaseDir
17217
- });
17218
- return factory.class.forDeletion({
17219
- baseDir: this.baseDir,
17220
- relativeDirPath: settablePaths.nonRoot?.relativeDirPath ?? ".",
17221
- relativeFilePath,
17222
- global: this.global
17223
- });
17224
- }).filter((rule) => rule.isDeletable());
18098
+ return buildDeletionRulesFromPaths(nonRootFilePaths, {
18099
+ baseDirOverride: nonRootBaseDir,
18100
+ relativeDirPathOverride: settablePaths.nonRoot.relativeDirPath
18101
+ });
17225
18102
  }
18103
+ const modularRootRelative = settablePaths.nonRoot.relativeDirPath;
18104
+ const nonRootPathsForImport = this.toolTarget === "rovodev" ? nonRootFilePaths.filter((filePath) => {
18105
+ const relativeFilePath = relative5(nonRootBaseDir, filePath);
18106
+ const ok = RovodevRule.isAllowedModularRulesRelativePath(relativeFilePath);
18107
+ if (!ok) {
18108
+ this.logger.warn(
18109
+ `Skipping reserved Rovodev path under modular-rules (import): ${join126(modularRootRelative, relativeFilePath)}`
18110
+ );
18111
+ }
18112
+ return ok;
18113
+ }) : nonRootFilePaths;
17226
18114
  return await Promise.all(
17227
- nonRootFilePaths.map((filePath) => {
18115
+ nonRootPathsForImport.map((filePath) => {
17228
18116
  const relativeFilePath = relative5(nonRootBaseDir, filePath);
17229
18117
  checkPathTraversal({
17230
18118
  relativePath: relativeFilePath,
@@ -17232,6 +18120,7 @@ var RulesProcessor = class extends FeatureProcessor {
17232
18120
  });
17233
18121
  return factory.class.fromFile({
17234
18122
  baseDir: this.baseDir,
18123
+ relativeDirPath: modularRootRelative,
17235
18124
  relativeFilePath,
17236
18125
  global: this.global
17237
18126
  });
@@ -17239,7 +18128,12 @@ var RulesProcessor = class extends FeatureProcessor {
17239
18128
  );
17240
18129
  })();
17241
18130
  this.logger.debug(`Found ${nonRootToolRules.length} non-root tool rule files`);
17242
- return [...rootToolRules, ...localRootToolRules, ...nonRootToolRules];
18131
+ return [
18132
+ ...rootToolRules,
18133
+ ...localRootToolRules,
18134
+ ...rovodevMirrorDeletionRules,
18135
+ ...nonRootToolRules
18136
+ ];
17243
18137
  } catch (error) {
17244
18138
  this.logger.error(`Failed to load tool files for ${this.toolTarget}: ${formatError(error)}`);
17245
18139
  return [];
@@ -17338,14 +18232,14 @@ s/<command> [arguments]
17338
18232
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
17339
18233
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
17340
18234
 
17341
- When users call a custom slash command, you have to look for the markdown file, \`${join122(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
18235
+ When users call a custom slash command, you have to look for the markdown file, \`${join126(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
17342
18236
  const subagentsSection = subagents ? `## Simulated Subagents
17343
18237
 
17344
18238
  Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
17345
18239
 
17346
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${join122(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
18240
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${join126(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
17347
18241
 
17348
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join122(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
18242
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join126(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
17349
18243
  const skillsSection = skills ? this.generateSkillsSection(skills) : "";
17350
18244
  const result = [
17351
18245
  overview,
@@ -17437,7 +18331,7 @@ function warnUnsupportedTargets(params) {
17437
18331
  }
17438
18332
  }
17439
18333
  async function checkRulesyncDirExists(params) {
17440
- return fileExists(join123(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
18334
+ return fileExists(join127(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
17441
18335
  }
17442
18336
  async function generate(params) {
17443
18337
  const { config, logger } = params;
@@ -18203,6 +19097,7 @@ export {
18203
19097
  FETCH_CONCURRENCY_LIMIT,
18204
19098
  formatError,
18205
19099
  ensureDir,
19100
+ toPosixPath,
18206
19101
  checkPathTraversal,
18207
19102
  directoryExists,
18208
19103
  readFileContent,