Skip to content

A tool for synchronizing LLM rules files with your dependencies.

Notifications You must be signed in to change notification settings

ash-project/usage_rules

CI License: MIT Hex version badge Hexdocs badge REUSE status

UsageRules

UsageRules is a config-driven dev tool for Elixir projects that manages your AGENTS.md file and agent skills from dependencies. It:

  • Gathers and consolidates usage-rules.md files from your dependencies into an AGENTS.md (or any file)
  • Generates agent skills (SKILL.md files) from dependency usage rules
  • Provides built-in usage rules for Elixir and OTP
  • Includes a powerful documentation search task via mix usage_rules.search_docs

Quickstart

Installation

If you have igniter installed:

mix igniter.install usage_rules

Or add usage_rules manually to your mix.exs:

def deps do
  [
    {:usage_rules, "~> 1.0", only: [:dev]},
    {:igniter, "~> 0.6", only: [:dev]}
  ]
end

Configuration

All configuration lives in your mix.exs project config. Add a :usage_rules key:

def project do
  [
    ...
    usage_rules: usage_rules()
  ]
end

defp usage_rules do
  # Example for those using claude.
  [
    file: "CLAUDE.md",
    # rules to include directly in CLAUDE.md
    usage_rules: ["usage_rules:all"],
    skills: [
      location: ".claude/skills",
      # build skills that combine multiple usage rules
      build: [
        "ash-framework": [
          # The description tells people how to use this skill.
          description: \"""
          Use this skill working with Ash Framework or any of its extensions. 
          Always consult this when making any domain changes, features or fixes.
          \""",
          # Include all Ash dependencies
          usage_rules: [:ash, ~r/^ash_/]
        ],
        "phoenix-framework": [
          description: \"""
          Use this skill working with Phoenix Framework.
          Consult this when working with the web layer, controllers, views, liveviews etc.
          \""",
          # Include all Phoenix dependencies
          usage_rules: [:phoenix, ~r/^phoenix_/]
        ]
      ]
    ]
  ]
end

Then run:

mix usage_rules.sync

That's it. The config is the source of truth — packages in the file but not in config are automatically removed on each sync.

Configuration Reference

defp usage_rules do
  [
    # The file to write usage rules into (required for usage_rules syncing)
    file: "AGENTS.md",

    # Which packages to include (required for usage_rules syncing)
    # :all discovers every dependency with a usage-rules.md and inlines them
    usage_rules: :all,
    # Or list specific packages and sub-rules:
    # usage_rules: [
    #   :ash,                         # inlined (default)
    #   "phoenix:ecto",               # specific sub-rule (inlined)
    #   {:req, link: :at},            # linked with @-style
    #   {:ecto, link: :markdown},     # linked with markdown-style
    #   :elixir,                      # built-in Elixir rules
    #   :otp,                         # built-in OTP rules
    # ],

    # Agent skills configuration
    skills: [
      location: ".claude/skills",  # where to output skills (default)

      # Auto-build a "use-<pkg>" skill per dependency
      deps: [:ash, :req],
      # Supports regex for matching multiple deps:
      # deps: [~r/^ash_/],
      # Use {:dep, :reference} to build as reference files instead of inlining:
      # deps: [:ash, {:req, :reference}, {~r/^ash_/, :reference}],

      # Compose custom skills from multiple packages
      build: [
        "ash-framework": [
          description: "Expert on the Ash Framework ecosystem.",
          # Use {:dep, :reference} or {~r/.../, :reference} for reference files
          usage_rules: [:ash, {:ash_postgres, :reference}, {~r/^ash_phoenix/, :reference}]
        ]
      ]
    ]
  ]
end

Config options

Option Type Description
file string Target file for usage rules (e.g. "AGENTS.md", "CLAUDE.md")
usage_rules :all | list Which packages to sync. :all auto-discovers, or list specific packages
skills keyword Agent skills configuration (see below)

Usage rules entry format

Each entry in the usage_rules list can be:

Format Description
:package Inline the package's usage rules (default)
"package:sub_rule" Inline a specific sub-rule
"package:all" Inline all sub-rules from a package
{:package, link: :at} Link with @deps/package/usage-rules.md style
{:package, link: :markdown} Link with [name](deps/package/usage-rules.md) style
{"package:sub_rule", link: :at} Link a specific sub-rule with @-style

Skills options

Option Type Description
location string Output directory for skills (default: ".claude/skills")
deps list Auto-build a use-<pkg> skill per listed dependency. Supports atoms, regexes, and {spec, :reference} tuples
build keyword Define custom composed skills from multiple packages' usage rules

Usage Rules

Sync all dependencies

The simplest setup — discover all deps with usage-rules.md and inline them:

defp usage_rules do
  [
    file: "AGENTS.md",
    usage_rules: :all
  ]
end

Specific packages

Pick exactly which packages to include:

defp usage_rules do
  [
    file: "AGENTS.md",
    usage_rules: [:ash, :phoenix, :ecto]
  ]
end

Sub-rules

Packages can provide sub-rules in a usage-rules/ directory. Reference them with "package:sub_rule" syntax:

usage_rules: [:phoenix, "phoenix:ecto", "phoenix:html"]

Use "package:all" to include all sub-rules from a package:

usage_rules: [:phoenix, "phoenix:all"]

Built-in aliases

UsageRules ships with built-in rules for Elixir and OTP:

usage_rules: [:elixir, :otp, :ash, :phoenix]

Linking instead of inlining

By default, usage rules are inlined directly into the target file. You can link to specific packages instead using the link option:

defp usage_rules do
  [
    file: "AGENTS.md",
    usage_rules: [
      :ash,                          # inlined
      {:phoenix, link: :at},         # @deps/phoenix/usage-rules.md
      {:ecto, link: :markdown},      # [ecto usage rules](deps/ecto/usage-rules.md)
      {"phoenix:html", link: :at}    # @deps/phoenix/usage-rules/html.md
    ]
  ]
end

Agent Skills

Skills are SKILL.md files that agent tools like Claude Code can discover and use. UsageRules can automatically generate skills from your dependencies' usage rules.

Generated skills use markers to delimit managed content. You can add custom content above the markers in any SKILL.md — it will be preserved across syncs.

Auto-build skills from deps

The deps option auto-builds a use-<package> skill for each listed dependency:

defp usage_rules do
  [
    file: "AGENTS.md",
    usage_rules: :all,
    skills: [
      deps: [:ash, :req]
    ]
  ]
end

This generates .claude/skills/use-ash/SKILL.md and .claude/skills/use-req/SKILL.md, each containing the package's usage rules, available mix tasks, doc search commands, and sub-rule references.

You can mark deps as :reference to have their main rules written as a separate reference file instead of being inlined into the skill body:

skills: [
  deps: [{:ash, :reference}, {~r/^ash_/, :reference}]
]

Compose custom skills

The build option lets you compose a single skill from multiple packages:

skills: [
  build: [
    "ash-framework": [
      description: "Expert on the Ash Framework ecosystem.",
      usage_rules: [:ash, :ash_postgres, :ash_phoenix, :ash_json_api]
    ]
  ]
]

This generates a single .claude/skills/ash-framework/SKILL.md that combines usage rules from all listed packages. Regex is also supported:

skills: [
  build: [
    "ash-framework": [
      description: "Expert on Ash.",
      usage_rules: [:ash, ~r/^ash_/]
    ]
  ]
]

Reference mode

By default, each package's main usage-rules.md is inlined directly into the skill body. For skills that combine many packages, this can make the SKILL.md quite large. You can use {:dep, :reference} or {~r/.../, :reference} to have packages built as separate reference files instead:

skills: [
  build: [
    "ash-framework": [
      description: "Expert on the Ash Framework ecosystem.",
      # Ash core rules are inlined, extensions are reference files
      usage_rules: [:ash, {~r/^ash_/, :reference}]
    ]
  ]
]

This inlines :ash's rules into the skill body and writes each matching extension's rules to references/<package>.md, linked from the "Additional References" section — the same way sub-rules are handled. This works in both deps and build configs, and with both atoms and regexes.

Stale skill cleanup

Skills generated by UsageRules include a managed-by: usage-rules marker in their YAML frontmatter. When a skill is removed from your config and you re-run mix usage_rules.sync, the stale skill files are automatically cleaned up. If you've added custom content to a managed skill, only the managed section is removed — your custom content is preserved.

Skills-only mode

You can use skills without syncing usage rules into a file — just omit the file and usage_rules keys:

defp usage_rules do
  [
    skills: [
      deps: [:ash, :phoenix]
    ]
  ]
end

Documentation Search

mix usage_rules.search_docs searches hexdocs with human-readable markdown output, designed for both humans and AI agents.

# Search all project dependencies
mix usage_rules.search_docs "search term"

# Search specific packages
mix usage_rules.search_docs "search term" -p ecto -p ash

# Search specific versions
mix usage_rules.search_docs "search term" -p ecto@3.13.2

# Search all packages on hex
mix usage_rules.search_docs "search term" --everywhere

# JSON output
mix usage_rules.search_docs "search term" --output json

# Search only in titles
mix usage_rules.search_docs "search term" --query-by title

# Pagination
mix usage_rules.search_docs "search term" --page 2 --per-page 20

For Package Authors

Even if you don't use LLMs yourself, your users likely do. Writing a usage-rules.md file helps prevent hallucination-driven support requests.

We don't really know what makes great usage-rules.md files yet. Ash Framework is experimenting with quite fleshed out usage rules which seems to be working quite well. See Ash Framework's usage-rules.md for one such large example. Perhaps for your package only a few lines are necessary.

One quick tip is to have an agent begin the work of writing rules for you, by pointing it at your docs and asking it to write a usage-rules.md file in a condensed format that would be useful for agents to work with your tool. Then, aggressively prune and edit it to your taste.

Make sure that your usage-rules.md file is included in your hex package's files option, so that it is distributed with your package.

Sub-rules

A package can provide a main usage-rules.md and/or sub-rule files:

usage-rules.md          # general rules
usage-rules/
  html.md               # html specific rules
  database.md           # database specific rules

Migrating from v0.1

v0.2 replaces CLI arguments with project config. If you were running:

mix usage_rules.sync AGENTS.md --all --link-to-folder deps

Replace it with config in mix.exs:

def project do
  [
    usage_rules: [
      file: "AGENTS.md",
      usage_rules: :all
    ]
  ]
end

Then just run mix usage_rules.sync with no arguments.

Migrating from v0.2

v1.0 removes link_to_folder, link_style, and inline options. Content is inlined by default. Use per-dep link option for linking:

# Before (v0.2)
usage_rules: :all,
link_to_folder: "deps",
link_style: "at",
inline: ["usage_rules:all"]

# After (v1.0)
usage_rules: [
  {:ash, link: :at},
  {:phoenix, link: :at},
  "usage_rules:all"    # inlined by default
]

About

A tool for synchronizing LLM rules files with your dependencies.

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 17

Languages