rulesync 7.30.0 → 8.1.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.
@@ -6501,7 +6501,8 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
6501
6501
  relativeDirPath: paths.relativeDirPath,
6502
6502
  relativeFilePath: paths.relativeFilePath,
6503
6503
  fileContent: JSON.stringify(newJson, null, 2),
6504
- validate
6504
+ validate,
6505
+ global
6505
6506
  });
6506
6507
  }
6507
6508
  static async fromRulesyncMcp({
@@ -6522,7 +6523,8 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
6522
6523
  relativeDirPath: paths.relativeDirPath,
6523
6524
  relativeFilePath: paths.relativeFilePath,
6524
6525
  fileContent: JSON.stringify(mcpJson, null, 2),
6525
- validate
6526
+ validate,
6527
+ global
6526
6528
  });
6527
6529
  }
6528
6530
  toRulesyncMcp() {
@@ -13493,12 +13495,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
13493
13495
  const body = rulesyncSubagent.getBody();
13494
13496
  const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
13495
13497
  const paths = this.getSettablePaths({ global });
13498
+ let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
13499
+ if (!relativeFilePath.endsWith(".agent.md")) {
13500
+ relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
13501
+ }
13496
13502
  return new _CopilotSubagent({
13497
13503
  baseDir,
13498
13504
  frontmatter: copilotFrontmatter,
13499
13505
  body,
13500
13506
  relativeDirPath: paths.relativeDirPath,
13501
- relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
13507
+ relativeFilePath,
13502
13508
  fileContent,
13503
13509
  validate,
13504
13510
  global
@@ -17931,14 +17937,21 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
17931
17937
  rulesyncRule,
17932
17938
  validate = true
17933
17939
  }) {
17934
- return new _WindsurfRule(
17935
- this.buildToolRuleParamsDefault({
17936
- baseDir,
17937
- rulesyncRule,
17938
- validate,
17939
- nonRootPath: this.getSettablePaths().nonRoot
17940
- })
17941
- );
17940
+ const toolRuleParams = this.buildToolRuleParamsDefault({
17941
+ baseDir,
17942
+ rulesyncRule,
17943
+ validate,
17944
+ nonRootPath: this.getSettablePaths().nonRoot
17945
+ });
17946
+ const windsurfFrontmatter = this.buildWindsurfFrontmatter({
17947
+ relativeFilePath: rulesyncRule.getRelativeFilePath(),
17948
+ description: rulesyncRule.getFrontmatter().description,
17949
+ globs: rulesyncRule.getFrontmatter().globs
17950
+ });
17951
+ return new _WindsurfRule({
17952
+ ...toolRuleParams,
17953
+ fileContent: stringifyFrontmatter(rulesyncRule.getBody(), windsurfFrontmatter)
17954
+ });
17942
17955
  }
17943
17956
  toRulesyncRule() {
17944
17957
  return this.toRulesyncRuleDefault();
@@ -17965,6 +17978,18 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
17965
17978
  toolTarget: "windsurf"
17966
17979
  });
17967
17980
  }
17981
+ static buildWindsurfFrontmatter({
17982
+ relativeFilePath,
17983
+ description,
17984
+ globs
17985
+ }) {
17986
+ const hasSpecificGlobs = Boolean(globs && globs.length > 0 && !globs.includes("**/*"));
17987
+ return {
17988
+ title: description ?? relativeFilePath.replace(/\.md$/, ""),
17989
+ trigger: hasSpecificGlobs ? "glob" : "always_on",
17990
+ ...hasSpecificGlobs && { globs }
17991
+ };
17992
+ }
17968
17993
  };
17969
17994
 
17970
17995
  // src/features/rules/rules-processor.ts
@@ -17997,6 +18022,42 @@ var rulesProcessorToolTargets = [
17997
18022
  ];
17998
18023
  var RulesProcessorToolTargetSchema = import_mini65.z.enum(rulesProcessorToolTargets);
17999
18024
  var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path131.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
18025
+ var RulesFeatureOptionsSchema = import_mini65.z.looseObject({
18026
+ ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"])),
18027
+ includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
18028
+ });
18029
+ var resolveRuleDiscoveryMode = ({
18030
+ defaultMode,
18031
+ options
18032
+ }) => {
18033
+ if (defaultMode === "claudecode-legacy") {
18034
+ return defaultMode;
18035
+ }
18036
+ if (!options) return defaultMode;
18037
+ const parsed = RulesFeatureOptionsSchema.safeParse(options);
18038
+ if (!parsed.success) {
18039
+ throw new Error(
18040
+ `Invalid options for rules feature: ${parsed.error.message}. \`ruleDiscoveryMode\` must be either "none" or "explicit".`
18041
+ );
18042
+ }
18043
+ if (!parsed.data.ruleDiscoveryMode) {
18044
+ return defaultMode;
18045
+ }
18046
+ return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
18047
+ };
18048
+ var IncludeLocalRootSchema = import_mini65.z.looseObject({
18049
+ includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
18050
+ });
18051
+ var resolveIncludeLocalRoot = (options) => {
18052
+ if (!options) return true;
18053
+ const parsed = IncludeLocalRootSchema.safeParse(options);
18054
+ if (!parsed.success) {
18055
+ throw new Error(
18056
+ `Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
18057
+ );
18058
+ }
18059
+ return parsed.data.includeLocalRoot ?? true;
18060
+ };
18000
18061
  var toolRuleFactories = /* @__PURE__ */ new Map([
18001
18062
  [
18002
18063
  "agentsmd",
@@ -18311,6 +18372,7 @@ var RulesProcessor = class extends FeatureProcessor {
18311
18372
  global;
18312
18373
  getFactory;
18313
18374
  skills;
18375
+ featureOptions;
18314
18376
  constructor({
18315
18377
  baseDir = process.cwd(),
18316
18378
  toolTarget,
@@ -18320,6 +18382,7 @@ var RulesProcessor = class extends FeatureProcessor {
18320
18382
  global = false,
18321
18383
  getFactory = defaultGetFactory6,
18322
18384
  skills,
18385
+ featureOptions,
18323
18386
  dryRun = false,
18324
18387
  logger: logger5
18325
18388
  }) {
@@ -18337,6 +18400,7 @@ var RulesProcessor = class extends FeatureProcessor {
18337
18400
  this.simulateSkills = simulateSkills;
18338
18401
  this.getFactory = getFactory;
18339
18402
  this.skills = skills;
18403
+ this.featureOptions = featureOptions;
18340
18404
  }
18341
18405
  async convertRulesyncFilesToToolFiles(rulesyncFiles) {
18342
18406
  const rulesyncRules = rulesyncFiles.filter(
@@ -18357,7 +18421,8 @@ var RulesProcessor = class extends FeatureProcessor {
18357
18421
  global: this.global
18358
18422
  });
18359
18423
  }).filter((rule) => rule !== null);
18360
- if (localRootRules.length > 0 && !this.global) {
18424
+ const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
18425
+ if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
18361
18426
  const localRootRule = localRootRules[0];
18362
18427
  if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
18363
18428
  this.handleLocalRootRule(toolRules, localRootRule, factory);
@@ -18494,7 +18559,11 @@ var RulesProcessor = class extends FeatureProcessor {
18494
18559
  * Generate reference section based on meta configuration.
18495
18560
  */
18496
18561
  generateReferenceSectionFromMeta(meta, toolRules) {
18497
- switch (meta.ruleDiscoveryMode) {
18562
+ const mode = resolveRuleDiscoveryMode({
18563
+ defaultMode: meta.ruleDiscoveryMode,
18564
+ options: this.featureOptions
18565
+ });
18566
+ switch (mode) {
18498
18567
  case "toon":
18499
18568
  return this.generateToonReferencesSection(toolRules);
18500
18569
  case "claudecode-legacy":
@@ -19935,6 +20004,7 @@ var ConfigParamsSchema = import_mini69.z.object({
19935
20004
  simulateCommands: (0, import_mini69.optional)(import_mini69.z.boolean()),
19936
20005
  simulateSubagents: (0, import_mini69.optional)(import_mini69.z.boolean()),
19937
20006
  simulateSkills: (0, import_mini69.optional)(import_mini69.z.boolean()),
20007
+ gitignoreTargetsOnly: (0, import_mini69.optional)(import_mini69.z.boolean()),
19938
20008
  dryRun: (0, import_mini69.optional)(import_mini69.z.boolean()),
19939
20009
  check: (0, import_mini69.optional)(import_mini69.z.boolean()),
19940
20010
  // Declarative skill sources
@@ -19962,6 +20032,7 @@ var Config = class _Config {
19962
20032
  simulateCommands;
19963
20033
  simulateSubagents;
19964
20034
  simulateSkills;
20035
+ gitignoreTargetsOnly;
19965
20036
  dryRun;
19966
20037
  check;
19967
20038
  sources;
@@ -19976,6 +20047,7 @@ var Config = class _Config {
19976
20047
  simulateCommands,
19977
20048
  simulateSubagents,
19978
20049
  simulateSkills,
20050
+ gitignoreTargetsOnly,
19979
20051
  dryRun,
19980
20052
  check,
19981
20053
  sources
@@ -19994,6 +20066,7 @@ var Config = class _Config {
19994
20066
  this.simulateCommands = simulateCommands ?? false;
19995
20067
  this.simulateSubagents = simulateSubagents ?? false;
19996
20068
  this.simulateSkills = simulateSkills ?? false;
20069
+ this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
19997
20070
  this.dryRun = dryRun ?? false;
19998
20071
  this.check = check ?? false;
19999
20072
  this.sources = sources ?? [];
@@ -20119,6 +20192,9 @@ var Config = class _Config {
20119
20192
  getSimulateSkills() {
20120
20193
  return this.simulateSkills;
20121
20194
  }
20195
+ getGitignoreTargetsOnly() {
20196
+ return this.gitignoreTargetsOnly;
20197
+ }
20122
20198
  getDryRun() {
20123
20199
  return this.dryRun;
20124
20200
  }
@@ -20150,6 +20226,7 @@ var getDefaults = () => ({
20150
20226
  simulateCommands: false,
20151
20227
  simulateSubagents: false,
20152
20228
  simulateSkills: false,
20229
+ gitignoreTargetsOnly: true,
20153
20230
  dryRun: false,
20154
20231
  check: false,
20155
20232
  sources: []
@@ -20176,6 +20253,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
20176
20253
  simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
20177
20254
  simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
20178
20255
  simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
20256
+ gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
20179
20257
  dryRun: localConfig.dryRun ?? baseConfig.dryRun,
20180
20258
  check: localConfig.check ?? baseConfig.check,
20181
20259
  sources: localConfig.sources ?? baseConfig.sources
@@ -20194,6 +20272,7 @@ var ConfigResolver = class {
20194
20272
  simulateCommands,
20195
20273
  simulateSubagents,
20196
20274
  simulateSkills,
20275
+ gitignoreTargetsOnly,
20197
20276
  dryRun,
20198
20277
  check
20199
20278
  }) {
@@ -20207,6 +20286,7 @@ var ConfigResolver = class {
20207
20286
  const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
20208
20287
  const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
20209
20288
  const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
20289
+ const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
20210
20290
  const configParams = {
20211
20291
  targets: targets ?? configByFile.targets ?? getDefaults().targets,
20212
20292
  features: features ?? configByFile.features ?? getDefaults().features,
@@ -20221,6 +20301,7 @@ var ConfigResolver = class {
20221
20301
  simulateCommands: resolvedSimulateCommands,
20222
20302
  simulateSubagents: resolvedSimulateSubagents,
20223
20303
  simulateSkills: resolvedSimulateSkills,
20304
+ gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
20224
20305
  dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
20225
20306
  check: check ?? configByFile.check ?? getDefaults().check,
20226
20307
  sources: configByFile.sources ?? getDefaults().sources
@@ -20243,11 +20324,11 @@ function getBaseDirsInLightOfGlobal({
20243
20324
  }
20244
20325
 
20245
20326
  // src/lib/generate.ts
20246
- var import_node_path138 = require("path");
20327
+ var import_node_path140 = require("path");
20247
20328
  var import_es_toolkit5 = require("es-toolkit");
20248
20329
 
20249
20330
  // src/features/permissions/permissions-processor.ts
20250
- var import_mini72 = require("zod/mini");
20331
+ var import_mini73 = require("zod/mini");
20251
20332
 
20252
20333
  // src/features/permissions/claudecode-permissions.ts
20253
20334
  var import_node_path136 = require("path");
@@ -20572,16 +20653,382 @@ function convertClaudeToRulesyncPermissions(params) {
20572
20653
  return { permission };
20573
20654
  }
20574
20655
 
20575
- // src/features/permissions/opencode-permissions.ts
20656
+ // src/features/permissions/codexcli-permissions.ts
20576
20657
  var import_node_path137 = require("path");
20577
- var import_jsonc_parser5 = require("jsonc-parser");
20658
+ var smolToml5 = __toESM(require("smol-toml"), 1);
20659
+ var RULESYNC_PROFILE_NAME = "rulesync";
20660
+ var CodexcliPermissions = class _CodexcliPermissions extends ToolPermissions {
20661
+ static getSettablePaths(_options = {}) {
20662
+ return {
20663
+ relativeDirPath: ".codex",
20664
+ relativeFilePath: "config.toml"
20665
+ };
20666
+ }
20667
+ isDeletable() {
20668
+ return false;
20669
+ }
20670
+ static async fromFile({
20671
+ baseDir = process.cwd(),
20672
+ validate = true,
20673
+ global = false
20674
+ }) {
20675
+ const paths = this.getSettablePaths({ global });
20676
+ const filePath = (0, import_node_path137.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
20677
+ const fileContent = await readFileContentOrNull(filePath) ?? smolToml5.stringify({});
20678
+ return new _CodexcliPermissions({
20679
+ baseDir,
20680
+ relativeDirPath: paths.relativeDirPath,
20681
+ relativeFilePath: paths.relativeFilePath,
20682
+ fileContent,
20683
+ validate
20684
+ });
20685
+ }
20686
+ static async fromRulesyncPermissions({
20687
+ baseDir = process.cwd(),
20688
+ rulesyncPermissions,
20689
+ validate = true,
20690
+ logger: logger5,
20691
+ global = false
20692
+ }) {
20693
+ const paths = this.getSettablePaths({ global });
20694
+ const filePath = (0, import_node_path137.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
20695
+ const existingContent = await readFileContentOrNull(filePath) ?? smolToml5.stringify({});
20696
+ const parsed = toMutableTable(smolToml5.parse(existingContent));
20697
+ const profile = convertRulesyncToCodexProfile({
20698
+ config: rulesyncPermissions.getJson(),
20699
+ logger: logger5
20700
+ });
20701
+ const permissionsTable = toMutableTable(parsed.permissions);
20702
+ permissionsTable[RULESYNC_PROFILE_NAME] = profile;
20703
+ parsed.permissions = permissionsTable;
20704
+ parsed.default_permissions = RULESYNC_PROFILE_NAME;
20705
+ return new _CodexcliPermissions({
20706
+ baseDir,
20707
+ relativeDirPath: paths.relativeDirPath,
20708
+ relativeFilePath: paths.relativeFilePath,
20709
+ fileContent: smolToml5.stringify(parsed),
20710
+ validate
20711
+ });
20712
+ }
20713
+ toRulesyncPermissions() {
20714
+ let parsed;
20715
+ try {
20716
+ parsed = smolToml5.parse(this.getFileContent());
20717
+ } catch (error) {
20718
+ throw new Error(
20719
+ `Failed to parse Codex CLI permissions content in ${(0, import_node_path137.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`,
20720
+ { cause: error }
20721
+ );
20722
+ }
20723
+ const table = toMutableTable(parsed);
20724
+ const defaultProfile = typeof table.default_permissions === "string" ? table.default_permissions : void 0;
20725
+ const permissionsTable = toMutableTable(table.permissions);
20726
+ const profile = toCodexProfile(permissionsTable[defaultProfile ?? RULESYNC_PROFILE_NAME]) ?? toCodexProfile(permissionsTable[RULESYNC_PROFILE_NAME]);
20727
+ const config = convertCodexProfileToRulesync(profile);
20728
+ return this.toRulesyncPermissionsDefault({
20729
+ fileContent: JSON.stringify(config, null, 2)
20730
+ });
20731
+ }
20732
+ validate() {
20733
+ return { success: true, error: null };
20734
+ }
20735
+ static forDeletion({
20736
+ baseDir = process.cwd(),
20737
+ relativeDirPath,
20738
+ relativeFilePath
20739
+ }) {
20740
+ return new _CodexcliPermissions({
20741
+ baseDir,
20742
+ relativeDirPath,
20743
+ relativeFilePath,
20744
+ fileContent: smolToml5.stringify({}),
20745
+ validate: false
20746
+ });
20747
+ }
20748
+ };
20749
+ function convertRulesyncToCodexProfile({
20750
+ config,
20751
+ logger: logger5
20752
+ }) {
20753
+ const filesystem = {};
20754
+ const domains = {};
20755
+ for (const [toolName, rules] of Object.entries(config.permission)) {
20756
+ if (toolName === "read") {
20757
+ for (const [pattern, action] of Object.entries(rules)) {
20758
+ filesystem[pattern] = mapReadAction(action);
20759
+ }
20760
+ continue;
20761
+ }
20762
+ if (toolName === "edit" || toolName === "write") {
20763
+ for (const [pattern, action] of Object.entries(rules)) {
20764
+ filesystem[pattern] = mapWriteAction(action);
20765
+ }
20766
+ continue;
20767
+ }
20768
+ if (toolName === "webfetch") {
20769
+ for (const [pattern, action] of Object.entries(rules)) {
20770
+ if (action === "ask") {
20771
+ logger5?.warn(
20772
+ `Codex CLI does not support "ask" for network domain permissions. Skipping webfetch rule: ${pattern}`
20773
+ );
20774
+ continue;
20775
+ }
20776
+ domains[pattern] = action;
20777
+ }
20778
+ continue;
20779
+ }
20780
+ logger5?.warn(
20781
+ `Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`
20782
+ );
20783
+ }
20784
+ return {
20785
+ ...Object.keys(filesystem).length > 0 ? { filesystem } : {},
20786
+ ...Object.keys(domains).length > 0 ? { network: { domains } } : {}
20787
+ };
20788
+ }
20789
+ function convertCodexProfileToRulesync(profile) {
20790
+ const permission = {};
20791
+ if (profile?.filesystem) {
20792
+ permission.read = {};
20793
+ permission.edit = {};
20794
+ for (const [pattern, access] of Object.entries(profile.filesystem)) {
20795
+ if (access === "none") {
20796
+ permission.read[pattern] = "deny";
20797
+ permission.edit[pattern] = "deny";
20798
+ } else if (access === "read") {
20799
+ permission.read[pattern] = "allow";
20800
+ } else {
20801
+ permission.edit[pattern] = "allow";
20802
+ }
20803
+ }
20804
+ }
20805
+ if (profile?.network?.domains) {
20806
+ permission.webfetch = {};
20807
+ for (const [domain, value] of Object.entries(profile.network.domains)) {
20808
+ permission.webfetch[domain] = value;
20809
+ }
20810
+ }
20811
+ return { permission };
20812
+ }
20813
+ function toCodexProfile(value) {
20814
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
20815
+ const table = toMutableTable(value);
20816
+ const filesystem = toFilesystemRecord(table.filesystem);
20817
+ const networkRaw = toMutableTable(table.network);
20818
+ const domains = toDomainRecord(networkRaw.domains);
20819
+ return {
20820
+ ...filesystem ? { filesystem } : {},
20821
+ ...domains ? { network: { domains } } : {}
20822
+ };
20823
+ }
20824
+ function toMutableTable(value) {
20825
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
20826
+ return {};
20827
+ }
20828
+ return { ...value };
20829
+ }
20830
+ function toFilesystemRecord(value) {
20831
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
20832
+ const result = {};
20833
+ for (const [key, raw] of Object.entries(value)) {
20834
+ if (typeof raw !== "string") continue;
20835
+ if (raw === "read" || raw === "write" || raw === "none") {
20836
+ result[key] = raw;
20837
+ }
20838
+ }
20839
+ return Object.keys(result).length > 0 ? result : void 0;
20840
+ }
20841
+ function toDomainRecord(value) {
20842
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
20843
+ const result = {};
20844
+ for (const [key, raw] of Object.entries(value)) {
20845
+ if (raw === "allow" || raw === "deny") {
20846
+ result[key] = raw;
20847
+ }
20848
+ }
20849
+ return Object.keys(result).length > 0 ? result : void 0;
20850
+ }
20851
+ function mapReadAction(action) {
20852
+ return action === "allow" ? "read" : "none";
20853
+ }
20854
+ function mapWriteAction(action) {
20855
+ return action === "allow" ? "write" : "none";
20856
+ }
20857
+
20858
+ // src/features/permissions/geminicli-permissions.ts
20859
+ var import_node_path138 = require("path");
20578
20860
  var import_mini71 = require("zod/mini");
20579
- var OpencodePermissionSchema = import_mini71.z.union([
20580
- import_mini71.z.enum(["allow", "ask", "deny"]),
20581
- import_mini71.z.record(import_mini71.z.string(), import_mini71.z.enum(["allow", "ask", "deny"]))
20861
+ var GeminiCliSettingsSchema = import_mini71.z.looseObject({
20862
+ tools: import_mini71.z.optional(
20863
+ import_mini71.z.looseObject({
20864
+ allowed: import_mini71.z.optional(import_mini71.z.array(import_mini71.z.string())),
20865
+ exclude: import_mini71.z.optional(import_mini71.z.array(import_mini71.z.string()))
20866
+ })
20867
+ )
20868
+ });
20869
+ var RULESYNC_TO_GEMINICLI_TOOL_NAME = {
20870
+ bash: "run_shell_command",
20871
+ read: "read_file",
20872
+ edit: "replace",
20873
+ write: "write_file",
20874
+ webfetch: "web_fetch"
20875
+ };
20876
+ var GeminicliPermissions = class _GeminicliPermissions extends ToolPermissions {
20877
+ static getSettablePaths(_options = {}) {
20878
+ return {
20879
+ relativeDirPath: ".gemini",
20880
+ relativeFilePath: "settings.json"
20881
+ };
20882
+ }
20883
+ isDeletable() {
20884
+ return false;
20885
+ }
20886
+ static async fromFile({
20887
+ baseDir = process.cwd(),
20888
+ validate = true,
20889
+ global = false
20890
+ }) {
20891
+ const paths = this.getSettablePaths({ global });
20892
+ const filePath = (0, import_node_path138.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
20893
+ const fileContent = await readFileContentOrNull(filePath) ?? JSON.stringify({}, null, 2);
20894
+ return new _GeminicliPermissions({
20895
+ baseDir,
20896
+ relativeDirPath: paths.relativeDirPath,
20897
+ relativeFilePath: paths.relativeFilePath,
20898
+ fileContent,
20899
+ validate
20900
+ });
20901
+ }
20902
+ static async fromRulesyncPermissions({
20903
+ baseDir = process.cwd(),
20904
+ rulesyncPermissions,
20905
+ validate = true,
20906
+ logger: logger5,
20907
+ global = false
20908
+ }) {
20909
+ const paths = this.getSettablePaths({ global });
20910
+ const filePath = (0, import_node_path138.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
20911
+ const existingContent = await readFileContentOrNull(filePath) ?? JSON.stringify({}, null, 2);
20912
+ const settingsResult = GeminiCliSettingsSchema.safeParse(JSON.parse(existingContent));
20913
+ if (!settingsResult.success) {
20914
+ throw new Error(
20915
+ `Failed to parse existing Gemini CLI settings at ${filePath}: ${formatError(settingsResult.error)}`
20916
+ );
20917
+ }
20918
+ const { allowed, exclude } = convertRulesyncToGeminicliTools({
20919
+ config: rulesyncPermissions.getJson(),
20920
+ logger: logger5
20921
+ });
20922
+ const merged = {
20923
+ ...settingsResult.data,
20924
+ tools: {
20925
+ ...settingsResult.data.tools,
20926
+ ...allowed.length > 0 ? { allowed } : {},
20927
+ ...exclude.length > 0 ? { exclude } : {}
20928
+ }
20929
+ };
20930
+ return new _GeminicliPermissions({
20931
+ baseDir,
20932
+ relativeDirPath: paths.relativeDirPath,
20933
+ relativeFilePath: paths.relativeFilePath,
20934
+ fileContent: JSON.stringify(merged, null, 2),
20935
+ validate
20936
+ });
20937
+ }
20938
+ toRulesyncPermissions() {
20939
+ let settings;
20940
+ try {
20941
+ const parsed = JSON.parse(this.getFileContent());
20942
+ settings = GeminiCliSettingsSchema.parse(parsed);
20943
+ } catch (error) {
20944
+ throw new Error(
20945
+ `Failed to parse Gemini CLI permissions content in ${(0, import_node_path138.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`,
20946
+ { cause: error }
20947
+ );
20948
+ }
20949
+ const permission = {};
20950
+ for (const toolEntry of settings.tools?.allowed ?? []) {
20951
+ const mapped = parseGeminicliToolEntry({ entry: toolEntry });
20952
+ const rules = permission[mapped.category] ??= {};
20953
+ rules[mapped.pattern] = "allow";
20954
+ }
20955
+ for (const toolEntry of settings.tools?.exclude ?? []) {
20956
+ const mapped = parseGeminicliToolEntry({ entry: toolEntry });
20957
+ const rules = permission[mapped.category] ??= {};
20958
+ rules[mapped.pattern] = "deny";
20959
+ }
20960
+ return this.toRulesyncPermissionsDefault({
20961
+ fileContent: JSON.stringify({ permission }, null, 2)
20962
+ });
20963
+ }
20964
+ validate() {
20965
+ return { success: true, error: null };
20966
+ }
20967
+ static forDeletion({
20968
+ baseDir = process.cwd(),
20969
+ relativeDirPath,
20970
+ relativeFilePath
20971
+ }) {
20972
+ return new _GeminicliPermissions({
20973
+ baseDir,
20974
+ relativeDirPath,
20975
+ relativeFilePath,
20976
+ fileContent: JSON.stringify({}, null, 2),
20977
+ validate: false
20978
+ });
20979
+ }
20980
+ };
20981
+ function convertRulesyncToGeminicliTools({
20982
+ config,
20983
+ logger: logger5
20984
+ }) {
20985
+ const allowed = [];
20986
+ const exclude = [];
20987
+ for (const [toolName, rules] of Object.entries(config.permission)) {
20988
+ const mappedToolName = RULESYNC_TO_GEMINICLI_TOOL_NAME[toolName] ?? toolName;
20989
+ if (!RULESYNC_TO_GEMINICLI_TOOL_NAME[toolName]) {
20990
+ logger5?.warn(`Gemini CLI permissions use direct tool names. Mapping as-is: ${toolName}`);
20991
+ }
20992
+ for (const [pattern, action] of Object.entries(rules)) {
20993
+ if (action === "ask") {
20994
+ logger5?.warn(
20995
+ `Gemini CLI does not support explicit "ask" rules in settings. Skipping ${toolName}:${pattern}`
20996
+ );
20997
+ continue;
20998
+ }
20999
+ const geminiEntry = pattern === "*" ? mappedToolName : `${mappedToolName}(${pattern})`;
21000
+ if (action === "allow") {
21001
+ allowed.push(geminiEntry);
21002
+ } else {
21003
+ exclude.push(geminiEntry);
21004
+ }
21005
+ }
21006
+ }
21007
+ return { allowed, exclude };
21008
+ }
21009
+ function parseGeminicliToolEntry({ entry }) {
21010
+ const match = /^([^()]+?)(?:\((.*)\))?$/.exec(entry);
21011
+ if (!match) return { category: entry, pattern: "*" };
21012
+ const rawToolName = match[1]?.trim() ?? entry;
21013
+ const mappedCategory = Object.entries(RULESYNC_TO_GEMINICLI_TOOL_NAME).find(
21014
+ ([, value]) => value === rawToolName
21015
+ )?.[0];
21016
+ return {
21017
+ category: mappedCategory ?? rawToolName,
21018
+ pattern: (match[2] ?? "*").trim()
21019
+ };
21020
+ }
21021
+
21022
+ // src/features/permissions/opencode-permissions.ts
21023
+ var import_node_path139 = require("path");
21024
+ var import_jsonc_parser5 = require("jsonc-parser");
21025
+ var import_mini72 = require("zod/mini");
21026
+ var OpencodePermissionSchema = import_mini72.z.union([
21027
+ import_mini72.z.enum(["allow", "ask", "deny"]),
21028
+ import_mini72.z.record(import_mini72.z.string(), import_mini72.z.enum(["allow", "ask", "deny"]))
20582
21029
  ]);
20583
- var OpencodePermissionsConfigSchema = import_mini71.z.looseObject({
20584
- permission: import_mini71.z.optional(import_mini71.z.record(import_mini71.z.string(), OpencodePermissionSchema))
21030
+ var OpencodePermissionsConfigSchema = import_mini72.z.looseObject({
21031
+ permission: import_mini72.z.optional(import_mini72.z.record(import_mini72.z.string(), OpencodePermissionSchema))
20585
21032
  });
20586
21033
  var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
20587
21034
  json;
@@ -20598,7 +21045,7 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
20598
21045
  static getSettablePaths({
20599
21046
  global = false
20600
21047
  } = {}) {
20601
- return global ? { relativeDirPath: (0, import_node_path137.join)(".config", "opencode"), relativeFilePath: "opencode.json" } : { relativeDirPath: ".", relativeFilePath: "opencode.json" };
21048
+ return global ? { relativeDirPath: (0, import_node_path139.join)(".config", "opencode"), relativeFilePath: "opencode.json" } : { relativeDirPath: ".", relativeFilePath: "opencode.json" };
20602
21049
  }
20603
21050
  static async fromFile({
20604
21051
  baseDir = process.cwd(),
@@ -20606,9 +21053,9 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
20606
21053
  global = false
20607
21054
  }) {
20608
21055
  const basePaths = _OpencodePermissions.getSettablePaths({ global });
20609
- const jsonDir = (0, import_node_path137.join)(baseDir, basePaths.relativeDirPath);
20610
- const jsoncPath = (0, import_node_path137.join)(jsonDir, "opencode.jsonc");
20611
- const jsonPath = (0, import_node_path137.join)(jsonDir, "opencode.json");
21056
+ const jsonDir = (0, import_node_path139.join)(baseDir, basePaths.relativeDirPath);
21057
+ const jsoncPath = (0, import_node_path139.join)(jsonDir, "opencode.jsonc");
21058
+ const jsonPath = (0, import_node_path139.join)(jsonDir, "opencode.json");
20612
21059
  let fileContent = await readFileContentOrNull(jsoncPath);
20613
21060
  let relativeFilePath = "opencode.jsonc";
20614
21061
  if (!fileContent) {
@@ -20633,9 +21080,9 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
20633
21080
  global = false
20634
21081
  }) {
20635
21082
  const basePaths = _OpencodePermissions.getSettablePaths({ global });
20636
- const jsonDir = (0, import_node_path137.join)(baseDir, basePaths.relativeDirPath);
20637
- const jsoncPath = (0, import_node_path137.join)(jsonDir, "opencode.jsonc");
20638
- const jsonPath = (0, import_node_path137.join)(jsonDir, "opencode.json");
21083
+ const jsonDir = (0, import_node_path139.join)(baseDir, basePaths.relativeDirPath);
21084
+ const jsoncPath = (0, import_node_path139.join)(jsonDir, "opencode.jsonc");
21085
+ const jsonPath = (0, import_node_path139.join)(jsonDir, "opencode.json");
20639
21086
  let fileContent = await readFileContentOrNull(jsoncPath);
20640
21087
  let relativeFilePath = "opencode.jsonc";
20641
21088
  if (!fileContent) {
@@ -20705,8 +21152,13 @@ var OpencodePermissions = class _OpencodePermissions extends ToolPermissions {
20705
21152
  };
20706
21153
 
20707
21154
  // src/features/permissions/permissions-processor.ts
20708
- var permissionsProcessorToolTargetTuple = ["claudecode", "opencode"];
20709
- var PermissionsProcessorToolTargetSchema = import_mini72.z.enum(permissionsProcessorToolTargetTuple);
21155
+ var permissionsProcessorToolTargetTuple = [
21156
+ "claudecode",
21157
+ "codexcli",
21158
+ "geminicli",
21159
+ "opencode"
21160
+ ];
21161
+ var PermissionsProcessorToolTargetSchema = import_mini73.z.enum(permissionsProcessorToolTargetTuple);
20710
21162
  var toolPermissionsFactories = /* @__PURE__ */ new Map([
20711
21163
  [
20712
21164
  "claudecode",
@@ -20719,6 +21171,28 @@ var toolPermissionsFactories = /* @__PURE__ */ new Map([
20719
21171
  }
20720
21172
  }
20721
21173
  ],
21174
+ [
21175
+ "codexcli",
21176
+ {
21177
+ class: CodexcliPermissions,
21178
+ meta: {
21179
+ supportsProject: true,
21180
+ supportsGlobal: true,
21181
+ supportsImport: true
21182
+ }
21183
+ }
21184
+ ],
21185
+ [
21186
+ "geminicli",
21187
+ {
21188
+ class: GeminicliPermissions,
21189
+ meta: {
21190
+ supportsProject: true,
21191
+ supportsGlobal: true,
21192
+ supportsImport: true
21193
+ }
21194
+ }
21195
+ ],
20722
21196
  [
20723
21197
  "opencode",
20724
21198
  {
@@ -20901,7 +21375,7 @@ function warnUnsupportedTargets(params) {
20901
21375
  }
20902
21376
  }
20903
21377
  async function checkRulesyncDirExists(params) {
20904
- return fileExists((0, import_node_path138.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
21378
+ return fileExists((0, import_node_path140.join)(params.baseDir, RULESYNC_RELATIVE_DIR_PATH));
20905
21379
  }
20906
21380
  async function generate(params) {
20907
21381
  const { config, logger: logger5 } = params;
@@ -20956,6 +21430,7 @@ async function generateRulesCore(params) {
20956
21430
  simulateSubagents: config.getSimulateSubagents(),
20957
21431
  simulateSkills: config.getSimulateSkills(),
20958
21432
  skills,
21433
+ featureOptions: config.getFeatureOptions(toolTarget, "rules"),
20959
21434
  dryRun: config.isPreviewMode(),
20960
21435
  logger: logger5
20961
21436
  });
@@ -21370,7 +21845,7 @@ async function generateCommand(logger5, options) {
21370
21845
  }
21371
21846
 
21372
21847
  // src/cli/commands/gitignore.ts
21373
- var import_node_path139 = require("path");
21848
+ var import_node_path141 = require("path");
21374
21849
 
21375
21850
  // src/cli/commands/gitignore-entries.ts
21376
21851
  var normalizeGitignoreEntryTargets = (target) => {
@@ -21416,6 +21891,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
21416
21891
  feature: "general",
21417
21892
  entry: "**/.claude/settings.local.json"
21418
21893
  },
21894
+ { target: "claudecode", feature: "general", entry: "**/.claude/*.lock" },
21419
21895
  // Cline
21420
21896
  { target: "cline", feature: "rules", entry: "**/.clinerules/" },
21421
21897
  { target: "cline", feature: "commands", entry: "**/.clinerules/workflows/" },
@@ -21524,6 +22000,11 @@ var GITIGNORE_ENTRY_REGISTRY = [
21524
22000
  { target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
21525
22001
  { target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
21526
22002
  { target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
22003
+ {
22004
+ target: "opencode",
22005
+ feature: "general",
22006
+ entry: "**/.opencode/package-lock.json"
22007
+ },
21527
22008
  // Qwen Code
21528
22009
  { target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
21529
22010
  { target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
@@ -21708,7 +22189,7 @@ var removeExistingRulesyncEntries = (content) => {
21708
22189
  return result;
21709
22190
  };
21710
22191
  var gitignoreCommand = async (logger5, options) => {
21711
- const gitignorePath = (0, import_node_path139.join)(process.cwd(), ".gitignore");
22192
+ const gitignorePath = (0, import_node_path141.join)(process.cwd(), ".gitignore");
21712
22193
  let gitignoreContent = "";
21713
22194
  if (await fileExists(gitignorePath)) {
21714
22195
  gitignoreContent = await readFileContent(gitignorePath);
@@ -22069,7 +22550,7 @@ async function importCommand(logger5, options) {
22069
22550
  }
22070
22551
 
22071
22552
  // src/lib/init.ts
22072
- var import_node_path140 = require("path");
22553
+ var import_node_path142 = require("path");
22073
22554
  async function init() {
22074
22555
  const sampleFiles = await createSampleFiles();
22075
22556
  const configFile = await createConfigFile();
@@ -22097,7 +22578,8 @@ async function createConfigFile() {
22097
22578
  global: false,
22098
22579
  simulateCommands: false,
22099
22580
  simulateSubagents: false,
22100
- simulateSkills: false
22581
+ simulateSkills: false,
22582
+ gitignoreTargetsOnly: true
22101
22583
  },
22102
22584
  null,
22103
22585
  2
@@ -22261,27 +22743,27 @@ Keep the summary concise and ready to reuse in future tasks.`
22261
22743
  await ensureDir(subagentPaths.relativeDirPath);
22262
22744
  await ensureDir(skillPaths.relativeDirPath);
22263
22745
  await ensureDir(ignorePaths.recommended.relativeDirPath);
22264
- const ruleFilepath = (0, import_node_path140.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
22746
+ const ruleFilepath = (0, import_node_path142.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
22265
22747
  results.push(await writeIfNotExists(ruleFilepath, sampleRuleFile.content));
22266
- const mcpFilepath = (0, import_node_path140.join)(
22748
+ const mcpFilepath = (0, import_node_path142.join)(
22267
22749
  mcpPaths.recommended.relativeDirPath,
22268
22750
  mcpPaths.recommended.relativeFilePath
22269
22751
  );
22270
22752
  results.push(await writeIfNotExists(mcpFilepath, sampleMcpFile.content));
22271
- const commandFilepath = (0, import_node_path140.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
22753
+ const commandFilepath = (0, import_node_path142.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
22272
22754
  results.push(await writeIfNotExists(commandFilepath, sampleCommandFile.content));
22273
- const subagentFilepath = (0, import_node_path140.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
22755
+ const subagentFilepath = (0, import_node_path142.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
22274
22756
  results.push(await writeIfNotExists(subagentFilepath, sampleSubagentFile.content));
22275
- const skillDirPath = (0, import_node_path140.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
22757
+ const skillDirPath = (0, import_node_path142.join)(skillPaths.relativeDirPath, sampleSkillFile.dirName);
22276
22758
  await ensureDir(skillDirPath);
22277
- const skillFilepath = (0, import_node_path140.join)(skillDirPath, SKILL_FILE_NAME);
22759
+ const skillFilepath = (0, import_node_path142.join)(skillDirPath, SKILL_FILE_NAME);
22278
22760
  results.push(await writeIfNotExists(skillFilepath, sampleSkillFile.content));
22279
- const ignoreFilepath = (0, import_node_path140.join)(
22761
+ const ignoreFilepath = (0, import_node_path142.join)(
22280
22762
  ignorePaths.recommended.relativeDirPath,
22281
22763
  ignorePaths.recommended.relativeFilePath
22282
22764
  );
22283
22765
  results.push(await writeIfNotExists(ignoreFilepath, sampleIgnoreFile.content));
22284
- const hooksFilepath = (0, import_node_path140.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
22766
+ const hooksFilepath = (0, import_node_path142.join)(hooksPaths.relativeDirPath, hooksPaths.relativeFilePath);
22285
22767
  results.push(await writeIfNotExists(hooksFilepath, sampleHooksFile.content));
22286
22768
  return results;
22287
22769
  }
@@ -22329,12 +22811,12 @@ async function initCommand(logger5) {
22329
22811
  }
22330
22812
 
22331
22813
  // src/lib/sources.ts
22332
- var import_node_path143 = require("path");
22814
+ var import_node_path145 = require("path");
22333
22815
  var import_promise2 = require("es-toolkit/promise");
22334
22816
 
22335
22817
  // src/lib/git-client.ts
22336
22818
  var import_node_child_process = require("child_process");
22337
- var import_node_path141 = require("path");
22819
+ var import_node_path143 = require("path");
22338
22820
  var import_node_util2 = require("util");
22339
22821
  var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
22340
22822
  var GIT_TIMEOUT_MS = 6e4;
@@ -22422,7 +22904,7 @@ async function fetchSkillFiles(params) {
22422
22904
  const { url, ref, skillsPath, logger: logger5 } = params;
22423
22905
  validateGitUrl(url, { logger: logger5 });
22424
22906
  validateRef(ref);
22425
- if (skillsPath.split(/[/\\]/).includes("..") || (0, import_node_path141.isAbsolute)(skillsPath)) {
22907
+ if (skillsPath.split(/[/\\]/).includes("..") || (0, import_node_path143.isAbsolute)(skillsPath)) {
22426
22908
  throw new GitClientError(
22427
22909
  `Invalid skillsPath "${skillsPath}": must be a relative path without ".."`
22428
22910
  );
@@ -22456,7 +22938,7 @@ async function fetchSkillFiles(params) {
22456
22938
  timeout: GIT_TIMEOUT_MS
22457
22939
  });
22458
22940
  await execFileAsync("git", ["-C", tmpDir, "checkout"], { timeout: GIT_TIMEOUT_MS });
22459
- const skillsDir = (0, import_node_path141.join)(tmpDir, skillsPath);
22941
+ const skillsDir = (0, import_node_path143.join)(tmpDir, skillsPath);
22460
22942
  if (!await directoryExists(skillsDir)) return [];
22461
22943
  return await walkDirectory(skillsDir, skillsDir, 0, { totalFiles: 0, totalSize: 0 }, logger5);
22462
22944
  } catch (error) {
@@ -22478,7 +22960,7 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
22478
22960
  const results = [];
22479
22961
  for (const name of await listDirectoryFiles(dir)) {
22480
22962
  if (name === ".git") continue;
22481
- const fullPath = (0, import_node_path141.join)(dir, name);
22963
+ const fullPath = (0, import_node_path143.join)(dir, name);
22482
22964
  if (await isSymlink(fullPath)) {
22483
22965
  logger5?.warn(`Skipping symlink "${fullPath}".`);
22484
22966
  continue;
@@ -22506,7 +22988,7 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
22506
22988
  );
22507
22989
  }
22508
22990
  const content = await readFileContent(fullPath);
22509
- results.push({ relativePath: (0, import_node_path141.relative)(baseDir, fullPath), content, size });
22991
+ results.push({ relativePath: (0, import_node_path143.relative)(baseDir, fullPath), content, size });
22510
22992
  }
22511
22993
  }
22512
22994
  return results;
@@ -22514,28 +22996,28 @@ async function walkDirectory(dir, baseDir, depth = 0, ctx = { totalFiles: 0, tot
22514
22996
 
22515
22997
  // src/lib/sources-lock.ts
22516
22998
  var import_node_crypto = require("crypto");
22517
- var import_node_path142 = require("path");
22518
- var import_mini73 = require("zod/mini");
22999
+ var import_node_path144 = require("path");
23000
+ var import_mini74 = require("zod/mini");
22519
23001
  var LOCKFILE_VERSION = 1;
22520
- var LockedSkillSchema = import_mini73.z.object({
22521
- integrity: import_mini73.z.string()
23002
+ var LockedSkillSchema = import_mini74.z.object({
23003
+ integrity: import_mini74.z.string()
22522
23004
  });
22523
- var LockedSourceSchema = import_mini73.z.object({
22524
- requestedRef: (0, import_mini73.optional)(import_mini73.z.string()),
22525
- resolvedRef: import_mini73.z.string().check((0, import_mini73.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolvedRef must be a 40-character hex SHA")),
22526
- resolvedAt: (0, import_mini73.optional)(import_mini73.z.string()),
22527
- skills: import_mini73.z.record(import_mini73.z.string(), LockedSkillSchema)
23005
+ var LockedSourceSchema = import_mini74.z.object({
23006
+ requestedRef: (0, import_mini74.optional)(import_mini74.z.string()),
23007
+ resolvedRef: import_mini74.z.string().check((0, import_mini74.refine)((v) => /^[0-9a-f]{40}$/.test(v), "resolvedRef must be a 40-character hex SHA")),
23008
+ resolvedAt: (0, import_mini74.optional)(import_mini74.z.string()),
23009
+ skills: import_mini74.z.record(import_mini74.z.string(), LockedSkillSchema)
22528
23010
  });
22529
- var SourcesLockSchema = import_mini73.z.object({
22530
- lockfileVersion: import_mini73.z.number(),
22531
- sources: import_mini73.z.record(import_mini73.z.string(), LockedSourceSchema)
23011
+ var SourcesLockSchema = import_mini74.z.object({
23012
+ lockfileVersion: import_mini74.z.number(),
23013
+ sources: import_mini74.z.record(import_mini74.z.string(), LockedSourceSchema)
22532
23014
  });
22533
- var LegacyLockedSourceSchema = import_mini73.z.object({
22534
- resolvedRef: import_mini73.z.string(),
22535
- skills: import_mini73.z.array(import_mini73.z.string())
23015
+ var LegacyLockedSourceSchema = import_mini74.z.object({
23016
+ resolvedRef: import_mini74.z.string(),
23017
+ skills: import_mini74.z.array(import_mini74.z.string())
22536
23018
  });
22537
- var LegacySourcesLockSchema = import_mini73.z.object({
22538
- sources: import_mini73.z.record(import_mini73.z.string(), LegacyLockedSourceSchema)
23019
+ var LegacySourcesLockSchema = import_mini74.z.object({
23020
+ sources: import_mini74.z.record(import_mini74.z.string(), LegacyLockedSourceSchema)
22539
23021
  });
22540
23022
  function migrateLegacyLock(params) {
22541
23023
  const { legacy, logger: logger5 } = params;
@@ -22560,7 +23042,7 @@ function createEmptyLock() {
22560
23042
  }
22561
23043
  async function readLockFile(params) {
22562
23044
  const { logger: logger5 } = params;
22563
- const lockPath = (0, import_node_path142.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
23045
+ const lockPath = (0, import_node_path144.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
22564
23046
  if (!await fileExists(lockPath)) {
22565
23047
  logger5.debug("No sources lockfile found, starting fresh.");
22566
23048
  return createEmptyLock();
@@ -22589,7 +23071,7 @@ async function readLockFile(params) {
22589
23071
  }
22590
23072
  async function writeLockFile(params) {
22591
23073
  const { logger: logger5 } = params;
22592
- const lockPath = (0, import_node_path142.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
23074
+ const lockPath = (0, import_node_path144.join)(params.baseDir, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH);
22593
23075
  const content = JSON.stringify(params.lock, null, 2) + "\n";
22594
23076
  await writeFileContent(lockPath, content);
22595
23077
  logger5.debug(`Wrote sources lockfile to ${lockPath}`);
@@ -22763,7 +23245,7 @@ function logGitClientHints(params) {
22763
23245
  async function checkLockedSkillsExist(curatedDir, skillNames) {
22764
23246
  if (skillNames.length === 0) return true;
22765
23247
  for (const name of skillNames) {
22766
- if (!await directoryExists((0, import_node_path143.join)(curatedDir, name))) {
23248
+ if (!await directoryExists((0, import_node_path145.join)(curatedDir, name))) {
22767
23249
  return false;
22768
23250
  }
22769
23251
  }
@@ -22771,10 +23253,10 @@ async function checkLockedSkillsExist(curatedDir, skillNames) {
22771
23253
  }
22772
23254
  async function cleanPreviousCuratedSkills(params) {
22773
23255
  const { curatedDir, lockedSkillNames, logger: logger5 } = params;
22774
- const resolvedCuratedDir = (0, import_node_path143.resolve)(curatedDir);
23256
+ const resolvedCuratedDir = (0, import_node_path145.resolve)(curatedDir);
22775
23257
  for (const prevSkill of lockedSkillNames) {
22776
- const prevDir = (0, import_node_path143.join)(curatedDir, prevSkill);
22777
- if (!(0, import_node_path143.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path143.sep)) {
23258
+ const prevDir = (0, import_node_path145.join)(curatedDir, prevSkill);
23259
+ if (!(0, import_node_path145.resolve)(prevDir).startsWith(resolvedCuratedDir + import_node_path145.sep)) {
22778
23260
  logger5.warn(
22779
23261
  `Skipping removal of "${prevSkill}": resolved path is outside the curated directory.`
22780
23262
  );
@@ -22813,9 +23295,9 @@ async function writeSkillAndComputeIntegrity(params) {
22813
23295
  for (const file of files) {
22814
23296
  checkPathTraversal({
22815
23297
  relativePath: file.relativePath,
22816
- intendedRootDir: (0, import_node_path143.join)(curatedDir, skillName)
23298
+ intendedRootDir: (0, import_node_path145.join)(curatedDir, skillName)
22817
23299
  });
22818
- await writeFileContent((0, import_node_path143.join)(curatedDir, skillName, file.relativePath), file.content);
23300
+ await writeFileContent((0, import_node_path145.join)(curatedDir, skillName, file.relativePath), file.content);
22819
23301
  written.push({ path: file.relativePath, content: file.content });
22820
23302
  }
22821
23303
  const integrity = computeSkillIntegrity(written);
@@ -22892,7 +23374,7 @@ async function fetchSource(params) {
22892
23374
  ref = resolvedSha;
22893
23375
  logger5.debug(`Resolved ${sourceKey} ref "${requestedRef}" to SHA: ${resolvedSha}`);
22894
23376
  }
22895
- const curatedDir = (0, import_node_path143.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
23377
+ const curatedDir = (0, import_node_path145.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
22896
23378
  if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
22897
23379
  const allExist = await checkLockedSkillsExist(curatedDir, lockedSkillNames);
22898
23380
  if (allExist) {
@@ -23017,7 +23499,7 @@ async function fetchSourceViaGit(params) {
23017
23499
  requestedRef = def.ref;
23018
23500
  resolvedSha = def.sha;
23019
23501
  }
23020
- const curatedDir = (0, import_node_path143.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
23502
+ const curatedDir = (0, import_node_path145.join)(baseDir, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH);
23021
23503
  if (locked && resolvedSha === locked.resolvedRef && !updateSources) {
23022
23504
  if (await checkLockedSkillsExist(curatedDir, lockedSkillNames)) {
23023
23505
  return { skillCount: 0, fetchedSkillNames: lockedSkillNames, updatedLock: lock };
@@ -23133,11 +23615,11 @@ async function installCommand(logger5, options) {
23133
23615
  var import_fastmcp = require("fastmcp");
23134
23616
 
23135
23617
  // src/mcp/tools.ts
23136
- var import_mini82 = require("zod/mini");
23618
+ var import_mini83 = require("zod/mini");
23137
23619
 
23138
23620
  // src/mcp/commands.ts
23139
- var import_node_path144 = require("path");
23140
- var import_mini74 = require("zod/mini");
23621
+ var import_node_path146 = require("path");
23622
+ var import_mini75 = require("zod/mini");
23141
23623
 
23142
23624
  // src/utils/logger.ts
23143
23625
  var BaseLogger = class {
@@ -23288,7 +23770,7 @@ var logger = new ConsoleLogger({ verbose: false, silent: true });
23288
23770
  var maxCommandSizeBytes = 1024 * 1024;
23289
23771
  var maxCommandsCount = 1e3;
23290
23772
  async function listCommands() {
23291
- const commandsDir = (0, import_node_path144.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
23773
+ const commandsDir = (0, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
23292
23774
  try {
23293
23775
  const files = await listDirectoryFiles(commandsDir);
23294
23776
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -23304,7 +23786,7 @@ async function listCommands() {
23304
23786
  });
23305
23787
  const frontmatter = command.getFrontmatter();
23306
23788
  return {
23307
- relativePathFromCwd: (0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
23789
+ relativePathFromCwd: (0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
23308
23790
  frontmatter
23309
23791
  };
23310
23792
  } catch (error) {
@@ -23326,13 +23808,13 @@ async function getCommand({ relativePathFromCwd }) {
23326
23808
  relativePath: relativePathFromCwd,
23327
23809
  intendedRootDir: process.cwd()
23328
23810
  });
23329
- const filename = (0, import_node_path144.basename)(relativePathFromCwd);
23811
+ const filename = (0, import_node_path146.basename)(relativePathFromCwd);
23330
23812
  try {
23331
23813
  const command = await RulesyncCommand.fromFile({
23332
23814
  relativeFilePath: filename
23333
23815
  });
23334
23816
  return {
23335
- relativePathFromCwd: (0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
23817
+ relativePathFromCwd: (0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
23336
23818
  frontmatter: command.getFrontmatter(),
23337
23819
  body: command.getBody()
23338
23820
  };
@@ -23351,7 +23833,7 @@ async function putCommand({
23351
23833
  relativePath: relativePathFromCwd,
23352
23834
  intendedRootDir: process.cwd()
23353
23835
  });
23354
- const filename = (0, import_node_path144.basename)(relativePathFromCwd);
23836
+ const filename = (0, import_node_path146.basename)(relativePathFromCwd);
23355
23837
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
23356
23838
  if (estimatedSize > maxCommandSizeBytes) {
23357
23839
  throw new Error(
@@ -23361,7 +23843,7 @@ async function putCommand({
23361
23843
  try {
23362
23844
  const existingCommands = await listCommands();
23363
23845
  const isUpdate = existingCommands.some(
23364
- (command2) => command2.relativePathFromCwd === (0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
23846
+ (command2) => command2.relativePathFromCwd === (0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
23365
23847
  );
23366
23848
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
23367
23849
  throw new Error(
@@ -23378,11 +23860,11 @@ async function putCommand({
23378
23860
  fileContent,
23379
23861
  validate: true
23380
23862
  });
23381
- const commandsDir = (0, import_node_path144.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
23863
+ const commandsDir = (0, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
23382
23864
  await ensureDir(commandsDir);
23383
23865
  await writeFileContent(command.getFilePath(), command.getFileContent());
23384
23866
  return {
23385
- relativePathFromCwd: (0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
23867
+ relativePathFromCwd: (0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
23386
23868
  frontmatter: command.getFrontmatter(),
23387
23869
  body: command.getBody()
23388
23870
  };
@@ -23397,12 +23879,12 @@ async function deleteCommand({ relativePathFromCwd }) {
23397
23879
  relativePath: relativePathFromCwd,
23398
23880
  intendedRootDir: process.cwd()
23399
23881
  });
23400
- const filename = (0, import_node_path144.basename)(relativePathFromCwd);
23401
- const fullPath = (0, import_node_path144.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
23882
+ const filename = (0, import_node_path146.basename)(relativePathFromCwd);
23883
+ const fullPath = (0, import_node_path146.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
23402
23884
  try {
23403
23885
  await removeFile(fullPath);
23404
23886
  return {
23405
- relativePathFromCwd: (0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
23887
+ relativePathFromCwd: (0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
23406
23888
  };
23407
23889
  } catch (error) {
23408
23890
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -23411,23 +23893,23 @@ async function deleteCommand({ relativePathFromCwd }) {
23411
23893
  }
23412
23894
  }
23413
23895
  var commandToolSchemas = {
23414
- listCommands: import_mini74.z.object({}),
23415
- getCommand: import_mini74.z.object({
23416
- relativePathFromCwd: import_mini74.z.string()
23896
+ listCommands: import_mini75.z.object({}),
23897
+ getCommand: import_mini75.z.object({
23898
+ relativePathFromCwd: import_mini75.z.string()
23417
23899
  }),
23418
- putCommand: import_mini74.z.object({
23419
- relativePathFromCwd: import_mini74.z.string(),
23900
+ putCommand: import_mini75.z.object({
23901
+ relativePathFromCwd: import_mini75.z.string(),
23420
23902
  frontmatter: RulesyncCommandFrontmatterSchema,
23421
- body: import_mini74.z.string()
23903
+ body: import_mini75.z.string()
23422
23904
  }),
23423
- deleteCommand: import_mini74.z.object({
23424
- relativePathFromCwd: import_mini74.z.string()
23905
+ deleteCommand: import_mini75.z.object({
23906
+ relativePathFromCwd: import_mini75.z.string()
23425
23907
  })
23426
23908
  };
23427
23909
  var commandTools = {
23428
23910
  listCommands: {
23429
23911
  name: "listCommands",
23430
- description: `List all commands from ${(0, import_node_path144.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
23912
+ description: `List all commands from ${(0, import_node_path146.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
23431
23913
  parameters: commandToolSchemas.listCommands,
23432
23914
  execute: async () => {
23433
23915
  const commands = await listCommands();
@@ -23469,15 +23951,15 @@ var commandTools = {
23469
23951
  };
23470
23952
 
23471
23953
  // src/mcp/generate.ts
23472
- var import_mini75 = require("zod/mini");
23473
- var generateOptionsSchema = import_mini75.z.object({
23474
- targets: import_mini75.z.optional(import_mini75.z.array(import_mini75.z.string())),
23475
- features: import_mini75.z.optional(import_mini75.z.array(import_mini75.z.string())),
23476
- delete: import_mini75.z.optional(import_mini75.z.boolean()),
23477
- global: import_mini75.z.optional(import_mini75.z.boolean()),
23478
- simulateCommands: import_mini75.z.optional(import_mini75.z.boolean()),
23479
- simulateSubagents: import_mini75.z.optional(import_mini75.z.boolean()),
23480
- simulateSkills: import_mini75.z.optional(import_mini75.z.boolean())
23954
+ var import_mini76 = require("zod/mini");
23955
+ var generateOptionsSchema = import_mini76.z.object({
23956
+ targets: import_mini76.z.optional(import_mini76.z.array(import_mini76.z.string())),
23957
+ features: import_mini76.z.optional(import_mini76.z.array(import_mini76.z.string())),
23958
+ delete: import_mini76.z.optional(import_mini76.z.boolean()),
23959
+ global: import_mini76.z.optional(import_mini76.z.boolean()),
23960
+ simulateCommands: import_mini76.z.optional(import_mini76.z.boolean()),
23961
+ simulateSubagents: import_mini76.z.optional(import_mini76.z.boolean()),
23962
+ simulateSkills: import_mini76.z.optional(import_mini76.z.boolean())
23481
23963
  });
23482
23964
  async function executeGenerate(options = {}) {
23483
23965
  try {
@@ -23556,11 +24038,11 @@ var generateTools = {
23556
24038
  };
23557
24039
 
23558
24040
  // src/mcp/ignore.ts
23559
- var import_node_path145 = require("path");
23560
- var import_mini76 = require("zod/mini");
24041
+ var import_node_path147 = require("path");
24042
+ var import_mini77 = require("zod/mini");
23561
24043
  var maxIgnoreFileSizeBytes = 100 * 1024;
23562
24044
  async function getIgnoreFile() {
23563
- const ignoreFilePath = (0, import_node_path145.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
24045
+ const ignoreFilePath = (0, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
23564
24046
  try {
23565
24047
  const content = await readFileContent(ignoreFilePath);
23566
24048
  return {
@@ -23577,7 +24059,7 @@ async function getIgnoreFile() {
23577
24059
  }
23578
24060
  }
23579
24061
  async function putIgnoreFile({ content }) {
23580
- const ignoreFilePath = (0, import_node_path145.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
24062
+ const ignoreFilePath = (0, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
23581
24063
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
23582
24064
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
23583
24065
  throw new Error(
@@ -23601,8 +24083,8 @@ async function putIgnoreFile({ content }) {
23601
24083
  }
23602
24084
  }
23603
24085
  async function deleteIgnoreFile() {
23604
- const aiignorePath = (0, import_node_path145.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
23605
- const legacyIgnorePath = (0, import_node_path145.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
24086
+ const aiignorePath = (0, import_node_path147.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
24087
+ const legacyIgnorePath = (0, import_node_path147.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
23606
24088
  try {
23607
24089
  await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
23608
24090
  return {
@@ -23620,11 +24102,11 @@ async function deleteIgnoreFile() {
23620
24102
  }
23621
24103
  }
23622
24104
  var ignoreToolSchemas = {
23623
- getIgnoreFile: import_mini76.z.object({}),
23624
- putIgnoreFile: import_mini76.z.object({
23625
- content: import_mini76.z.string()
24105
+ getIgnoreFile: import_mini77.z.object({}),
24106
+ putIgnoreFile: import_mini77.z.object({
24107
+ content: import_mini77.z.string()
23626
24108
  }),
23627
- deleteIgnoreFile: import_mini76.z.object({})
24109
+ deleteIgnoreFile: import_mini77.z.object({})
23628
24110
  };
23629
24111
  var ignoreTools = {
23630
24112
  getIgnoreFile: {
@@ -23657,11 +24139,11 @@ var ignoreTools = {
23657
24139
  };
23658
24140
 
23659
24141
  // src/mcp/import.ts
23660
- var import_mini77 = require("zod/mini");
23661
- var importOptionsSchema = import_mini77.z.object({
23662
- target: import_mini77.z.string(),
23663
- features: import_mini77.z.optional(import_mini77.z.array(import_mini77.z.string())),
23664
- global: import_mini77.z.optional(import_mini77.z.boolean())
24142
+ var import_mini78 = require("zod/mini");
24143
+ var importOptionsSchema = import_mini78.z.object({
24144
+ target: import_mini78.z.string(),
24145
+ features: import_mini78.z.optional(import_mini78.z.array(import_mini78.z.string())),
24146
+ global: import_mini78.z.optional(import_mini78.z.boolean())
23665
24147
  });
23666
24148
  async function executeImport(options) {
23667
24149
  try {
@@ -23732,15 +24214,15 @@ var importTools = {
23732
24214
  };
23733
24215
 
23734
24216
  // src/mcp/mcp.ts
23735
- var import_node_path146 = require("path");
23736
- var import_mini78 = require("zod/mini");
24217
+ var import_node_path148 = require("path");
24218
+ var import_mini79 = require("zod/mini");
23737
24219
  var maxMcpSizeBytes = 1024 * 1024;
23738
24220
  async function getMcpFile() {
23739
24221
  try {
23740
24222
  const rulesyncMcp = await RulesyncMcp.fromFile({
23741
24223
  validate: true
23742
24224
  });
23743
- const relativePathFromCwd = (0, import_node_path146.join)(
24225
+ const relativePathFromCwd = (0, import_node_path148.join)(
23744
24226
  rulesyncMcp.getRelativeDirPath(),
23745
24227
  rulesyncMcp.getRelativeFilePath()
23746
24228
  );
@@ -23778,7 +24260,7 @@ async function putMcpFile({ content }) {
23778
24260
  const paths = RulesyncMcp.getSettablePaths();
23779
24261
  const relativeDirPath = paths.recommended.relativeDirPath;
23780
24262
  const relativeFilePath = paths.recommended.relativeFilePath;
23781
- const fullPath = (0, import_node_path146.join)(baseDir, relativeDirPath, relativeFilePath);
24263
+ const fullPath = (0, import_node_path148.join)(baseDir, relativeDirPath, relativeFilePath);
23782
24264
  const rulesyncMcp = new RulesyncMcp({
23783
24265
  baseDir,
23784
24266
  relativeDirPath,
@@ -23786,9 +24268,9 @@ async function putMcpFile({ content }) {
23786
24268
  fileContent: content,
23787
24269
  validate: true
23788
24270
  });
23789
- await ensureDir((0, import_node_path146.join)(baseDir, relativeDirPath));
24271
+ await ensureDir((0, import_node_path148.join)(baseDir, relativeDirPath));
23790
24272
  await writeFileContent(fullPath, content);
23791
- const relativePathFromCwd = (0, import_node_path146.join)(relativeDirPath, relativeFilePath);
24273
+ const relativePathFromCwd = (0, import_node_path148.join)(relativeDirPath, relativeFilePath);
23792
24274
  return {
23793
24275
  relativePathFromCwd,
23794
24276
  content: rulesyncMcp.getFileContent()
@@ -23806,15 +24288,15 @@ async function deleteMcpFile() {
23806
24288
  try {
23807
24289
  const baseDir = process.cwd();
23808
24290
  const paths = RulesyncMcp.getSettablePaths();
23809
- const recommendedPath = (0, import_node_path146.join)(
24291
+ const recommendedPath = (0, import_node_path148.join)(
23810
24292
  baseDir,
23811
24293
  paths.recommended.relativeDirPath,
23812
24294
  paths.recommended.relativeFilePath
23813
24295
  );
23814
- const legacyPath = (0, import_node_path146.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
24296
+ const legacyPath = (0, import_node_path148.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
23815
24297
  await removeFile(recommendedPath);
23816
24298
  await removeFile(legacyPath);
23817
- const relativePathFromCwd = (0, import_node_path146.join)(
24299
+ const relativePathFromCwd = (0, import_node_path148.join)(
23818
24300
  paths.recommended.relativeDirPath,
23819
24301
  paths.recommended.relativeFilePath
23820
24302
  );
@@ -23831,11 +24313,11 @@ async function deleteMcpFile() {
23831
24313
  }
23832
24314
  }
23833
24315
  var mcpToolSchemas = {
23834
- getMcpFile: import_mini78.z.object({}),
23835
- putMcpFile: import_mini78.z.object({
23836
- content: import_mini78.z.string()
24316
+ getMcpFile: import_mini79.z.object({}),
24317
+ putMcpFile: import_mini79.z.object({
24318
+ content: import_mini79.z.string()
23837
24319
  }),
23838
- deleteMcpFile: import_mini78.z.object({})
24320
+ deleteMcpFile: import_mini79.z.object({})
23839
24321
  };
23840
24322
  var mcpTools = {
23841
24323
  getMcpFile: {
@@ -23868,13 +24350,13 @@ var mcpTools = {
23868
24350
  };
23869
24351
 
23870
24352
  // src/mcp/rules.ts
23871
- var import_node_path147 = require("path");
23872
- var import_mini79 = require("zod/mini");
24353
+ var import_node_path149 = require("path");
24354
+ var import_mini80 = require("zod/mini");
23873
24355
  var logger2 = new ConsoleLogger({ verbose: false, silent: true });
23874
24356
  var maxRuleSizeBytes = 1024 * 1024;
23875
24357
  var maxRulesCount = 1e3;
23876
24358
  async function listRules() {
23877
- const rulesDir = (0, import_node_path147.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
24359
+ const rulesDir = (0, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
23878
24360
  try {
23879
24361
  const files = await listDirectoryFiles(rulesDir);
23880
24362
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -23887,7 +24369,7 @@ async function listRules() {
23887
24369
  });
23888
24370
  const frontmatter = rule.getFrontmatter();
23889
24371
  return {
23890
- relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
24372
+ relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
23891
24373
  frontmatter
23892
24374
  };
23893
24375
  } catch (error) {
@@ -23909,14 +24391,14 @@ async function getRule({ relativePathFromCwd }) {
23909
24391
  relativePath: relativePathFromCwd,
23910
24392
  intendedRootDir: process.cwd()
23911
24393
  });
23912
- const filename = (0, import_node_path147.basename)(relativePathFromCwd);
24394
+ const filename = (0, import_node_path149.basename)(relativePathFromCwd);
23913
24395
  try {
23914
24396
  const rule = await RulesyncRule.fromFile({
23915
24397
  relativeFilePath: filename,
23916
24398
  validate: true
23917
24399
  });
23918
24400
  return {
23919
- relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
24401
+ relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
23920
24402
  frontmatter: rule.getFrontmatter(),
23921
24403
  body: rule.getBody()
23922
24404
  };
@@ -23935,7 +24417,7 @@ async function putRule({
23935
24417
  relativePath: relativePathFromCwd,
23936
24418
  intendedRootDir: process.cwd()
23937
24419
  });
23938
- const filename = (0, import_node_path147.basename)(relativePathFromCwd);
24420
+ const filename = (0, import_node_path149.basename)(relativePathFromCwd);
23939
24421
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
23940
24422
  if (estimatedSize > maxRuleSizeBytes) {
23941
24423
  throw new Error(
@@ -23945,7 +24427,7 @@ async function putRule({
23945
24427
  try {
23946
24428
  const existingRules = await listRules();
23947
24429
  const isUpdate = existingRules.some(
23948
- (rule2) => rule2.relativePathFromCwd === (0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
24430
+ (rule2) => rule2.relativePathFromCwd === (0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
23949
24431
  );
23950
24432
  if (!isUpdate && existingRules.length >= maxRulesCount) {
23951
24433
  throw new Error(
@@ -23960,11 +24442,11 @@ async function putRule({
23960
24442
  body,
23961
24443
  validate: true
23962
24444
  });
23963
- const rulesDir = (0, import_node_path147.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
24445
+ const rulesDir = (0, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
23964
24446
  await ensureDir(rulesDir);
23965
24447
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
23966
24448
  return {
23967
- relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
24449
+ relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
23968
24450
  frontmatter: rule.getFrontmatter(),
23969
24451
  body: rule.getBody()
23970
24452
  };
@@ -23979,12 +24461,12 @@ async function deleteRule({ relativePathFromCwd }) {
23979
24461
  relativePath: relativePathFromCwd,
23980
24462
  intendedRootDir: process.cwd()
23981
24463
  });
23982
- const filename = (0, import_node_path147.basename)(relativePathFromCwd);
23983
- const fullPath = (0, import_node_path147.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
24464
+ const filename = (0, import_node_path149.basename)(relativePathFromCwd);
24465
+ const fullPath = (0, import_node_path149.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
23984
24466
  try {
23985
24467
  await removeFile(fullPath);
23986
24468
  return {
23987
- relativePathFromCwd: (0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
24469
+ relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
23988
24470
  };
23989
24471
  } catch (error) {
23990
24472
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -23993,23 +24475,23 @@ async function deleteRule({ relativePathFromCwd }) {
23993
24475
  }
23994
24476
  }
23995
24477
  var ruleToolSchemas = {
23996
- listRules: import_mini79.z.object({}),
23997
- getRule: import_mini79.z.object({
23998
- relativePathFromCwd: import_mini79.z.string()
24478
+ listRules: import_mini80.z.object({}),
24479
+ getRule: import_mini80.z.object({
24480
+ relativePathFromCwd: import_mini80.z.string()
23999
24481
  }),
24000
- putRule: import_mini79.z.object({
24001
- relativePathFromCwd: import_mini79.z.string(),
24482
+ putRule: import_mini80.z.object({
24483
+ relativePathFromCwd: import_mini80.z.string(),
24002
24484
  frontmatter: RulesyncRuleFrontmatterSchema,
24003
- body: import_mini79.z.string()
24485
+ body: import_mini80.z.string()
24004
24486
  }),
24005
- deleteRule: import_mini79.z.object({
24006
- relativePathFromCwd: import_mini79.z.string()
24487
+ deleteRule: import_mini80.z.object({
24488
+ relativePathFromCwd: import_mini80.z.string()
24007
24489
  })
24008
24490
  };
24009
24491
  var ruleTools = {
24010
24492
  listRules: {
24011
24493
  name: "listRules",
24012
- description: `List all rules from ${(0, import_node_path147.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
24494
+ description: `List all rules from ${(0, import_node_path149.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
24013
24495
  parameters: ruleToolSchemas.listRules,
24014
24496
  execute: async () => {
24015
24497
  const rules = await listRules();
@@ -24051,8 +24533,8 @@ var ruleTools = {
24051
24533
  };
24052
24534
 
24053
24535
  // src/mcp/skills.ts
24054
- var import_node_path148 = require("path");
24055
- var import_mini80 = require("zod/mini");
24536
+ var import_node_path150 = require("path");
24537
+ var import_mini81 = require("zod/mini");
24056
24538
  var logger3 = new ConsoleLogger({ verbose: false, silent: true });
24057
24539
  var maxSkillSizeBytes = 1024 * 1024;
24058
24540
  var maxSkillsCount = 1e3;
@@ -24069,19 +24551,19 @@ function mcpSkillFileToAiDirFile(file) {
24069
24551
  };
24070
24552
  }
24071
24553
  function extractDirName(relativeDirPathFromCwd) {
24072
- const dirName = (0, import_node_path148.basename)(relativeDirPathFromCwd);
24554
+ const dirName = (0, import_node_path150.basename)(relativeDirPathFromCwd);
24073
24555
  if (!dirName) {
24074
24556
  throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
24075
24557
  }
24076
24558
  return dirName;
24077
24559
  }
24078
24560
  async function listSkills() {
24079
- const skillsDir = (0, import_node_path148.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
24561
+ const skillsDir = (0, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
24080
24562
  try {
24081
- const skillDirPaths = await findFilesByGlobs((0, import_node_path148.join)(skillsDir, "*"), { type: "dir" });
24563
+ const skillDirPaths = await findFilesByGlobs((0, import_node_path150.join)(skillsDir, "*"), { type: "dir" });
24082
24564
  const skills = await Promise.all(
24083
24565
  skillDirPaths.map(async (dirPath) => {
24084
- const dirName = (0, import_node_path148.basename)(dirPath);
24566
+ const dirName = (0, import_node_path150.basename)(dirPath);
24085
24567
  if (!dirName) return null;
24086
24568
  try {
24087
24569
  const skill = await RulesyncSkill.fromDir({
@@ -24089,7 +24571,7 @@ async function listSkills() {
24089
24571
  });
24090
24572
  const frontmatter = skill.getFrontmatter();
24091
24573
  return {
24092
- relativeDirPathFromCwd: (0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24574
+ relativeDirPathFromCwd: (0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24093
24575
  frontmatter
24094
24576
  };
24095
24577
  } catch (error) {
@@ -24117,7 +24599,7 @@ async function getSkill({ relativeDirPathFromCwd }) {
24117
24599
  dirName
24118
24600
  });
24119
24601
  return {
24120
- relativeDirPathFromCwd: (0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24602
+ relativeDirPathFromCwd: (0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24121
24603
  frontmatter: skill.getFrontmatter(),
24122
24604
  body: skill.getBody(),
24123
24605
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -24151,7 +24633,7 @@ async function putSkill({
24151
24633
  try {
24152
24634
  const existingSkills = await listSkills();
24153
24635
  const isUpdate = existingSkills.some(
24154
- (skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
24636
+ (skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
24155
24637
  );
24156
24638
  if (!isUpdate && existingSkills.length >= maxSkillsCount) {
24157
24639
  throw new Error(
@@ -24168,9 +24650,9 @@ async function putSkill({
24168
24650
  otherFiles: aiDirFiles,
24169
24651
  validate: true
24170
24652
  });
24171
- const skillDirPath = (0, import_node_path148.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
24653
+ const skillDirPath = (0, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
24172
24654
  await ensureDir(skillDirPath);
24173
- const skillFilePath = (0, import_node_path148.join)(skillDirPath, SKILL_FILE_NAME);
24655
+ const skillFilePath = (0, import_node_path150.join)(skillDirPath, SKILL_FILE_NAME);
24174
24656
  const skillFileContent = stringifyFrontmatter(body, frontmatter);
24175
24657
  await writeFileContent(skillFilePath, skillFileContent);
24176
24658
  for (const file of otherFiles) {
@@ -24178,15 +24660,15 @@ async function putSkill({
24178
24660
  relativePath: file.name,
24179
24661
  intendedRootDir: skillDirPath
24180
24662
  });
24181
- const filePath = (0, import_node_path148.join)(skillDirPath, file.name);
24182
- const fileDir = (0, import_node_path148.join)(skillDirPath, (0, import_node_path148.dirname)(file.name));
24663
+ const filePath = (0, import_node_path150.join)(skillDirPath, file.name);
24664
+ const fileDir = (0, import_node_path150.join)(skillDirPath, (0, import_node_path150.dirname)(file.name));
24183
24665
  if (fileDir !== skillDirPath) {
24184
24666
  await ensureDir(fileDir);
24185
24667
  }
24186
24668
  await writeFileContent(filePath, file.body);
24187
24669
  }
24188
24670
  return {
24189
- relativeDirPathFromCwd: (0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24671
+ relativeDirPathFromCwd: (0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
24190
24672
  frontmatter: skill.getFrontmatter(),
24191
24673
  body: skill.getBody(),
24192
24674
  otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
@@ -24208,13 +24690,13 @@ async function deleteSkill({
24208
24690
  intendedRootDir: process.cwd()
24209
24691
  });
24210
24692
  const dirName = extractDirName(relativeDirPathFromCwd);
24211
- const skillDirPath = (0, import_node_path148.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
24693
+ const skillDirPath = (0, import_node_path150.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
24212
24694
  try {
24213
24695
  if (await directoryExists(skillDirPath)) {
24214
24696
  await removeDirectory(skillDirPath);
24215
24697
  }
24216
24698
  return {
24217
- relativeDirPathFromCwd: (0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
24699
+ relativeDirPathFromCwd: (0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
24218
24700
  };
24219
24701
  } catch (error) {
24220
24702
  throw new Error(
@@ -24225,29 +24707,29 @@ async function deleteSkill({
24225
24707
  );
24226
24708
  }
24227
24709
  }
24228
- var McpSkillFileSchema = import_mini80.z.object({
24229
- name: import_mini80.z.string(),
24230
- body: import_mini80.z.string()
24710
+ var McpSkillFileSchema = import_mini81.z.object({
24711
+ name: import_mini81.z.string(),
24712
+ body: import_mini81.z.string()
24231
24713
  });
24232
24714
  var skillToolSchemas = {
24233
- listSkills: import_mini80.z.object({}),
24234
- getSkill: import_mini80.z.object({
24235
- relativeDirPathFromCwd: import_mini80.z.string()
24715
+ listSkills: import_mini81.z.object({}),
24716
+ getSkill: import_mini81.z.object({
24717
+ relativeDirPathFromCwd: import_mini81.z.string()
24236
24718
  }),
24237
- putSkill: import_mini80.z.object({
24238
- relativeDirPathFromCwd: import_mini80.z.string(),
24719
+ putSkill: import_mini81.z.object({
24720
+ relativeDirPathFromCwd: import_mini81.z.string(),
24239
24721
  frontmatter: RulesyncSkillFrontmatterSchema,
24240
- body: import_mini80.z.string(),
24241
- otherFiles: import_mini80.z.optional(import_mini80.z.array(McpSkillFileSchema))
24722
+ body: import_mini81.z.string(),
24723
+ otherFiles: import_mini81.z.optional(import_mini81.z.array(McpSkillFileSchema))
24242
24724
  }),
24243
- deleteSkill: import_mini80.z.object({
24244
- relativeDirPathFromCwd: import_mini80.z.string()
24725
+ deleteSkill: import_mini81.z.object({
24726
+ relativeDirPathFromCwd: import_mini81.z.string()
24245
24727
  })
24246
24728
  };
24247
24729
  var skillTools = {
24248
24730
  listSkills: {
24249
24731
  name: "listSkills",
24250
- description: `List all skills from ${(0, import_node_path148.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
24732
+ description: `List all skills from ${(0, import_node_path150.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
24251
24733
  parameters: skillToolSchemas.listSkills,
24252
24734
  execute: async () => {
24253
24735
  const skills = await listSkills();
@@ -24290,13 +24772,13 @@ var skillTools = {
24290
24772
  };
24291
24773
 
24292
24774
  // src/mcp/subagents.ts
24293
- var import_node_path149 = require("path");
24294
- var import_mini81 = require("zod/mini");
24775
+ var import_node_path151 = require("path");
24776
+ var import_mini82 = require("zod/mini");
24295
24777
  var logger4 = new ConsoleLogger({ verbose: false, silent: true });
24296
24778
  var maxSubagentSizeBytes = 1024 * 1024;
24297
24779
  var maxSubagentsCount = 1e3;
24298
24780
  async function listSubagents() {
24299
- const subagentsDir = (0, import_node_path149.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
24781
+ const subagentsDir = (0, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
24300
24782
  try {
24301
24783
  const files = await listDirectoryFiles(subagentsDir);
24302
24784
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -24309,7 +24791,7 @@ async function listSubagents() {
24309
24791
  });
24310
24792
  const frontmatter = subagent.getFrontmatter();
24311
24793
  return {
24312
- relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
24794
+ relativePathFromCwd: (0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
24313
24795
  frontmatter
24314
24796
  };
24315
24797
  } catch (error) {
@@ -24333,14 +24815,14 @@ async function getSubagent({ relativePathFromCwd }) {
24333
24815
  relativePath: relativePathFromCwd,
24334
24816
  intendedRootDir: process.cwd()
24335
24817
  });
24336
- const filename = (0, import_node_path149.basename)(relativePathFromCwd);
24818
+ const filename = (0, import_node_path151.basename)(relativePathFromCwd);
24337
24819
  try {
24338
24820
  const subagent = await RulesyncSubagent.fromFile({
24339
24821
  relativeFilePath: filename,
24340
24822
  validate: true
24341
24823
  });
24342
24824
  return {
24343
- relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
24825
+ relativePathFromCwd: (0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
24344
24826
  frontmatter: subagent.getFrontmatter(),
24345
24827
  body: subagent.getBody()
24346
24828
  };
@@ -24359,7 +24841,7 @@ async function putSubagent({
24359
24841
  relativePath: relativePathFromCwd,
24360
24842
  intendedRootDir: process.cwd()
24361
24843
  });
24362
- const filename = (0, import_node_path149.basename)(relativePathFromCwd);
24844
+ const filename = (0, import_node_path151.basename)(relativePathFromCwd);
24363
24845
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
24364
24846
  if (estimatedSize > maxSubagentSizeBytes) {
24365
24847
  throw new Error(
@@ -24369,7 +24851,7 @@ async function putSubagent({
24369
24851
  try {
24370
24852
  const existingSubagents = await listSubagents();
24371
24853
  const isUpdate = existingSubagents.some(
24372
- (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
24854
+ (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
24373
24855
  );
24374
24856
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
24375
24857
  throw new Error(
@@ -24384,11 +24866,11 @@ async function putSubagent({
24384
24866
  body,
24385
24867
  validate: true
24386
24868
  });
24387
- const subagentsDir = (0, import_node_path149.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
24869
+ const subagentsDir = (0, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
24388
24870
  await ensureDir(subagentsDir);
24389
24871
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
24390
24872
  return {
24391
- relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
24873
+ relativePathFromCwd: (0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
24392
24874
  frontmatter: subagent.getFrontmatter(),
24393
24875
  body: subagent.getBody()
24394
24876
  };
@@ -24403,12 +24885,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
24403
24885
  relativePath: relativePathFromCwd,
24404
24886
  intendedRootDir: process.cwd()
24405
24887
  });
24406
- const filename = (0, import_node_path149.basename)(relativePathFromCwd);
24407
- const fullPath = (0, import_node_path149.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
24888
+ const filename = (0, import_node_path151.basename)(relativePathFromCwd);
24889
+ const fullPath = (0, import_node_path151.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
24408
24890
  try {
24409
24891
  await removeFile(fullPath);
24410
24892
  return {
24411
- relativePathFromCwd: (0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
24893
+ relativePathFromCwd: (0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
24412
24894
  };
24413
24895
  } catch (error) {
24414
24896
  throw new Error(
@@ -24420,23 +24902,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
24420
24902
  }
24421
24903
  }
24422
24904
  var subagentToolSchemas = {
24423
- listSubagents: import_mini81.z.object({}),
24424
- getSubagent: import_mini81.z.object({
24425
- relativePathFromCwd: import_mini81.z.string()
24905
+ listSubagents: import_mini82.z.object({}),
24906
+ getSubagent: import_mini82.z.object({
24907
+ relativePathFromCwd: import_mini82.z.string()
24426
24908
  }),
24427
- putSubagent: import_mini81.z.object({
24428
- relativePathFromCwd: import_mini81.z.string(),
24909
+ putSubagent: import_mini82.z.object({
24910
+ relativePathFromCwd: import_mini82.z.string(),
24429
24911
  frontmatter: RulesyncSubagentFrontmatterSchema,
24430
- body: import_mini81.z.string()
24912
+ body: import_mini82.z.string()
24431
24913
  }),
24432
- deleteSubagent: import_mini81.z.object({
24433
- relativePathFromCwd: import_mini81.z.string()
24914
+ deleteSubagent: import_mini82.z.object({
24915
+ relativePathFromCwd: import_mini82.z.string()
24434
24916
  })
24435
24917
  };
24436
24918
  var subagentTools = {
24437
24919
  listSubagents: {
24438
24920
  name: "listSubagents",
24439
- description: `List all subagents from ${(0, import_node_path149.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
24921
+ description: `List all subagents from ${(0, import_node_path151.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
24440
24922
  parameters: subagentToolSchemas.listSubagents,
24441
24923
  execute: async () => {
24442
24924
  const subagents = await listSubagents();
@@ -24478,7 +24960,7 @@ var subagentTools = {
24478
24960
  };
24479
24961
 
24480
24962
  // src/mcp/tools.ts
24481
- var rulesyncFeatureSchema = import_mini82.z.enum([
24963
+ var rulesyncFeatureSchema = import_mini83.z.enum([
24482
24964
  "rule",
24483
24965
  "command",
24484
24966
  "subagent",
@@ -24488,21 +24970,21 @@ var rulesyncFeatureSchema = import_mini82.z.enum([
24488
24970
  "generate",
24489
24971
  "import"
24490
24972
  ]);
24491
- var rulesyncOperationSchema = import_mini82.z.enum(["list", "get", "put", "delete", "run"]);
24492
- var skillFileSchema = import_mini82.z.object({
24493
- name: import_mini82.z.string(),
24494
- body: import_mini82.z.string()
24973
+ var rulesyncOperationSchema = import_mini83.z.enum(["list", "get", "put", "delete", "run"]);
24974
+ var skillFileSchema = import_mini83.z.object({
24975
+ name: import_mini83.z.string(),
24976
+ body: import_mini83.z.string()
24495
24977
  });
24496
- var rulesyncToolSchema = import_mini82.z.object({
24978
+ var rulesyncToolSchema = import_mini83.z.object({
24497
24979
  feature: rulesyncFeatureSchema,
24498
24980
  operation: rulesyncOperationSchema,
24499
- targetPathFromCwd: import_mini82.z.optional(import_mini82.z.string()),
24500
- frontmatter: import_mini82.z.optional(import_mini82.z.unknown()),
24501
- body: import_mini82.z.optional(import_mini82.z.string()),
24502
- otherFiles: import_mini82.z.optional(import_mini82.z.array(skillFileSchema)),
24503
- content: import_mini82.z.optional(import_mini82.z.string()),
24504
- generateOptions: import_mini82.z.optional(generateOptionsSchema),
24505
- importOptions: import_mini82.z.optional(importOptionsSchema)
24981
+ targetPathFromCwd: import_mini83.z.optional(import_mini83.z.string()),
24982
+ frontmatter: import_mini83.z.optional(import_mini83.z.unknown()),
24983
+ body: import_mini83.z.optional(import_mini83.z.string()),
24984
+ otherFiles: import_mini83.z.optional(import_mini83.z.array(skillFileSchema)),
24985
+ content: import_mini83.z.optional(import_mini83.z.string()),
24986
+ generateOptions: import_mini83.z.optional(generateOptionsSchema),
24987
+ importOptions: import_mini83.z.optional(importOptionsSchema)
24506
24988
  });
24507
24989
  var supportedOperationsByFeature = {
24508
24990
  rule: ["list", "get", "put", "delete"],
@@ -24708,6 +25190,31 @@ async function mcpCommand(logger5, { version }) {
24708
25190
  });
24709
25191
  }
24710
25192
 
25193
+ // src/cli/commands/resolve-gitignore-targets.ts
25194
+ var import_node_path152 = require("path");
25195
+ var resolveGitignoreTargets = async ({
25196
+ cliTargets,
25197
+ cwd = process.cwd()
25198
+ }) => {
25199
+ if (cliTargets !== void 0) {
25200
+ return cliTargets;
25201
+ }
25202
+ const baseConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
25203
+ const localConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
25204
+ const [hasBase, hasLocal] = await Promise.all([
25205
+ fileExists(baseConfigPath),
25206
+ fileExists(localConfigPath)
25207
+ ]);
25208
+ if (!hasBase && !hasLocal) {
25209
+ return void 0;
25210
+ }
25211
+ const config = await ConfigResolver.resolve({});
25212
+ if (config.getGitignoreTargetsOnly()) {
25213
+ return config.getTargets();
25214
+ }
25215
+ return void 0;
25216
+ };
25217
+
24711
25218
  // src/lib/update.ts
24712
25219
  var crypto = __toESM(require("crypto"), 1);
24713
25220
  var fs = __toESM(require("fs"), 1);
@@ -25110,7 +25617,7 @@ function wrapCommand({
25110
25617
  }
25111
25618
 
25112
25619
  // src/cli/index.ts
25113
- var getVersion = () => "7.30.0";
25620
+ var getVersion = () => "8.1.0";
25114
25621
  function wrapCommand2(name, errorCode, handler) {
25115
25622
  return wrapCommand({ name, errorCode, handler, getVersion });
25116
25623
  }
@@ -25133,11 +25640,12 @@ var main = async () => {
25133
25640
  parseCommaSeparatedList
25134
25641
  ).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
25135
25642
  wrapCommand2("gitignore", "GITIGNORE_FAILED", async (logger5, options) => {
25643
+ const cliTargets = options.targets;
25644
+ const cliFeatures = options.features;
25645
+ const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
25136
25646
  await gitignoreCommand(logger5, {
25137
- // eslint-disable-next-line no-type-assertion/no-type-assertion
25138
- targets: options.targets,
25139
- // eslint-disable-next-line no-type-assertion/no-type-assertion
25140
- features: options.features
25647
+ targets: resolvedTargets ? [...resolvedTargets] : void 0,
25648
+ features: cliFeatures
25141
25649
  });
25142
25650
  })
25143
25651
  );