{"id":30269009,"url":"https://github.com/ash-project/usage_rules","last_synced_at":"2026-03-02T05:07:57.571Z","repository":{"id":294998060,"uuid":"988748052","full_name":"ash-project/usage_rules","owner":"ash-project","description":"A tool for synchronizing LLM rules files with your dependencies.","archived":false,"fork":false,"pushed_at":"2026-02-17T01:32:54.000Z","size":219,"stargazers_count":154,"open_issues_count":2,"forks_count":28,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-17T02:06:17.150Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ash-project.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSES/MIT.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"ash-framework"}},"created_at":"2025-05-23T02:43:05.000Z","updated_at":"2026-02-17T01:32:50.000Z","dependencies_parsed_at":"2026-01-02T07:07:53.343Z","dependency_job_id":null,"html_url":"https://github.com/ash-project/usage_rules","commit_stats":null,"previous_names":["ash-project/usage_rules"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/ash-project/usage_rules","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ash-project%2Fusage_rules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ash-project%2Fusage_rules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ash-project%2Fusage_rules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ash-project%2Fusage_rules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ash-project","download_url":"https://codeload.github.com/ash-project/usage_rules/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ash-project%2Fusage_rules/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29566366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T00:47:08.760Z","status":"online","status_checked_at":"2026-02-18T02:00:09.468Z","response_time":162,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-16T01:37:25.065Z","updated_at":"2026-02-18T02:11:06.185Z","avatar_url":"https://github.com/ash-project.png","language":"Elixir","funding_links":["https://opencollective.com/ash-framework"],"categories":["Observability, Evaluation \u0026 Guardrails","Generative AI"],"sub_categories":["How to Join","Development Tools"],"readme":"\u003c!--\nSPDX-FileCopyrightText: 2025 Zach Daniel\nSPDX-FileCopyrightText: 2025 usage_rules contributors \u003chttps://github.com/ash-project/usage_rules/graphs/contributors\u003e\n\nSPDX-License-Identifier: MIT\n--\u003e\n[![CI](https://github.com/ash-project/usage_rules/actions/workflows/elixir.yml/badge.svg)](https://github.com/ash-project/usage_rules/actions/workflows/elixir.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Hex version badge](https://img.shields.io/hexpm/v/usage_rules.svg)](https://hex.pm/packages/usage_rules)\n[![Hexdocs badge](https://img.shields.io/badge/docs-hexdocs-purple)](https://hexdocs.pm/usage_rules)\n[![REUSE status](https://api.reuse.software/badge/github.com/ash-project/usage_rules)](https://api.reuse.software/info/github.com/ash-project/usage_rules)\n\n# UsageRules\n\n**UsageRules** is a config-driven dev tool for Elixir projects that manages your AGENTS.md file and agent skills from dependencies. It:\n\n- Gathers and consolidates `usage-rules.md` files (or files from a `usage-rules` directory) from your dependencies into an `AGENTS.md` (or any file)\n- Generates agent skills (`SKILL.md` files) from dependency usage rules\n- Provides built-in usage rules for Elixir and OTP\n- Includes a powerful documentation search task via `mix usage_rules.search_docs`\n\n## Quickstart\n\n### Installation\n\nIf you have [igniter](https://github.com/ash-project/igniter) installed:\n\n```sh\nmix igniter.install usage_rules\n```\n\nOr add `usage_rules` manually to your `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:usage_rules, \"~\u003e 1.1\", only: [:dev]},\n    {:igniter, \"~\u003e 0.6\", only: [:dev]}\n  ]\nend\n```\n\n### Configuration\n\nAll configuration lives in your `mix.exs` project config. Add a `:usage_rules` key:\n\n```elixir\ndef project do\n  [\n    ...\n    usage_rules: usage_rules()\n  ]\nend\n\ndefp usage_rules do\n  # Example for those using claude.\n  [\n    file: \"CLAUDE.md\",\n    # rules to include directly in CLAUDE.md\n    # use a regex to match multiple deps, or atoms/strings for specific ones\n    usage_rules: [:ash, ~r/^ash_/],\n    # If your CLAUDE.md is getting too big, link instead of inlining:\n    usage_rules: [:ash, {~r/^ash_/, link: :markdown}],\n    # or use skills\n    skills: [\n      location: \".claude/skills\",\n      # build skills that combine multiple usage rules\n      build: [\n        \"ash-framework\": [\n          # The description tells people how to use this skill.\n          description: \"Use this skill working with Ash Framework or any of its extensions. Always consult this when making any domain changes, features or fixes.\",\n          # Include all Ash dependencies\n          usage_rules: [:ash, ~r/^ash_/]\n        ],\n        \"phoenix-framework\": [\n          description: \"Use this skill working with Phoenix Framework. Consult this when working with the web layer, controllers, views, liveviews etc.\",\n          # Include all Phoenix dependencies\n          usage_rules: [:phoenix, ~r/^phoenix_/]\n        ]\n      ]\n    ]\n  ]\nend\n```\n\nThen run:\n\n```sh\nmix usage_rules.sync\n```\n\nThat's it. The config is the source of truth — packages in the file but not in config are automatically removed on each sync.\n\n## Configuration Reference\n\n```elixir\ndefp usage_rules do\n  [\n    # The file to write usage rules into (required for usage_rules syncing)\n    file: \"AGENTS.md\",\n\n    # Which packages to include (required for usage_rules syncing)\n    # :all discovers every dependency with a usage-rules.md and inlines them\n    usage_rules: :all,\n    # Or list specific packages and sub-rules:\n    # usage_rules: [\n    #   :ash,                         # inlined (default)\n    #   ~r/^ash_/,                    # regex match (inlined)\n    #   \"phoenix:ecto\",               # specific sub-rule (inlined)\n    #   {:req, link: :at},            # linked with @-style\n    #   {:ecto, link: :markdown},     # linked with markdown-style\n    #   {~r/^phoenix_/, link: :markdown}, # regex match (linked)\n    #   :elixir,                      # built-in Elixir rules\n    #   :otp,                         # built-in OTP rules\n    # ],\n\n    # Agent skills configuration\n    skills: [\n      location: \".claude/skills\",  # where to output skills (default)\n\n      # Auto-build a \"use-\u003cpkg\u003e\" skill per dependency\n      deps: [:ash, :req],\n      # Supports regex for matching multiple deps:\n      # deps: [~r/^ash_/],\n\n      # Compose custom skills from multiple packages\n      build: [\n        \"ash-framework\": [\n          description: \"Expert on the Ash Framework ecosystem.\",\n          usage_rules: [:ash, ~r/^ash_/]\n        ]\n      ]\n    ]\n  ]\nend\n```\n\n### Config options\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `file` | `string` | Target file for usage rules (e.g. `\"AGENTS.md\"`, `\"CLAUDE.md\"`) |\n| `usage_rules` | `:all \\| list` | Which packages to sync. `:all` auto-discovers, or list specific packages |\n| `skills` | `keyword` | Agent skills configuration (see below) |\n\n### Usage rules entry format\n\nEach entry in the `usage_rules` list can be:\n\n| Format | Description |\n|--------|-------------|\n| `:package` | Inline the package's usage rules (default) |\n| `\"package:sub_rule\"` | Inline a specific sub-rule |\n| `\"package:all\"` | Inline all sub-rules from a package |\n| `~r/pattern/` | Inline all matching dependencies' usage rules |\n| `{:package, link: :at}` | Link with `@deps/package/usage-rules.md` style |\n| `{:package, link: :markdown}` | Link with `[name](deps/package/usage-rules.md)` style |\n| `{~r/pattern/, link: :markdown}` | Link all matching dependencies with markdown-style |\n| `{\"package:sub_rule\", link: :at}` | Link a specific sub-rule with @-style |\n| `{:package, main: false}` | Exclude the main `usage-rules.md`, include only sub-rules |\n\n### Skills options\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `location` | `string` | Output directory for skills (default: `\".claude/skills\"`) |\n| `deps` | `list` | Auto-build a `use-\u003cpkg\u003e` skill per listed dependency. Supports atoms and regexes |\n| `build` | `keyword` | Define custom composed skills from multiple packages' usage rules |\n\n## Usage Rules\n\n### Sync all dependencies\n\nThe simplest setup — discover all deps with `usage-rules.md` and inline them:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: :all\n  ]\nend\n```\n\n### Specific packages\n\nPick exactly which packages to include:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: [:ash, :phoenix, :ecto]\n  ]\nend\n```\n\n### Sub-rules\n\nPackages can provide sub-rules in a `usage-rules/` directory. Reference them with `\"package:sub_rule\"` syntax:\n\n```elixir\nusage_rules: [:phoenix, \"phoenix:ecto\", \"phoenix:html\"]\n```\n\nUse `\"package:all\"` to include all sub-rules from a package:\n\n```elixir\nusage_rules: [:phoenix, \"phoenix:all\"]\n```\n\n### Built-in aliases\n\nUsageRules ships with built-in rules for Elixir and OTP:\n\n```elixir\nusage_rules: [:elixir, :otp, :ash, :phoenix]\n```\n\n### Matching by regex\n\nUse a regex to match multiple dependencies at once:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: [:ash, ~r/^ash_/]\n    # If your AGENTS.md is getting too big, link instead of inlining:\n    # usage_rules: [:ash, {~r/^ash_/, link: :markdown}]\n  ]\nend\n```\n\nThis matches all dependencies whose name matches the regex and inlines their `usage-rules.md`. Dependencies without a `usage-rules.md` are silently skipped.\n\n### Linking instead of inlining\n\nBy default, usage rules are inlined directly into the target file. You can link to specific packages instead using the `link` option:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: [\n      :ash,                          # inlined\n      {:phoenix, link: :at},         # @deps/phoenix/usage-rules.md\n      {:ecto, link: :markdown},      # [ecto usage rules](deps/ecto/usage-rules.md)\n      {\"phoenix:html\", link: :at}    # @deps/phoenix/usage-rules/html.md\n    ]\n  ]\nend\n```\n\n### Inline main rules, link sub-rules\n\nIf a package has many sub-rules and you want to keep the main rules inlined but link to sub-rules instead of inlining them all, use `main: false` to declare the same package twice with different options:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: [\n      {:ash, sub_rules: []},                                  # inline main rules only\n      {:ash, sub_rules: :all, main: false, link: :markdown}   # link sub-rules only\n    ]\n  ]\nend\n```\n\nThe first entry inlines the main `usage-rules.md` with no sub-rules. The second entry adds all sub-rules as markdown links, with `main: false` preventing a duplicate main entry.\n\n## Agent Skills\n\nSkills are SKILL.md files that agent tools like Claude Code can discover and use. UsageRules can automatically generate skills from your dependencies' usage rules.\n\nGenerated 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.\n\n### Auto-build skills from deps\n\nThe `deps` option auto-builds a `use-\u003cpackage\u003e` skill for each listed dependency:\n\n```elixir\ndefp usage_rules do\n  [\n    file: \"AGENTS.md\",\n    usage_rules: :all,\n    skills: [\n      deps: [:ash, :req]\n    ]\n  ]\nend\n```\n\nThis generates `.claude/skills/use-ash/SKILL.md` and `.claude/skills/use-req/SKILL.md`, each with reference links to the package's usage rules, available mix tasks, doc search commands, and sub-rule references. Each package's `usage-rules.md` is written to a `references/\u003cpackage\u003e.md` file.\n\n### Compose custom skills\n\nThe `build` option lets you compose a single skill from multiple packages:\n\n```elixir\nskills: [\n  build: [\n    \"ash-framework\": [\n      description: \"Expert on the Ash Framework ecosystem.\",\n      usage_rules: [:ash, :ash_postgres, :ash_phoenix, :ash_json_api]\n    ]\n  ]\n]\n```\n\nThis generates a single `.claude/skills/ash-framework/SKILL.md` with reference links to usage rules from all listed packages. Each package's rules are written to `references/\u003cpackage\u003e.md`. Regex is also supported:\n\n```elixir\nskills: [\n  build: [\n    \"ash-framework\": [\n      description: \"Expert on Ash.\",\n      usage_rules: [:ash, ~r/^ash_/]\n    ]\n  ]\n]\n```\n\n### Stale skill cleanup\n\nSkills 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.\n\n### Skills-only mode\n\nYou can use skills without syncing usage rules into a file — just omit the `file` and `usage_rules` keys:\n\n```elixir\ndefp usage_rules do\n  [\n    skills: [\n      deps: [:ash, :phoenix]\n    ]\n  ]\nend\n```\n\n## Documentation Search\n\n`mix usage_rules.search_docs` searches hexdocs with human-readable markdown output, designed for both humans and AI agents.\n\n```sh\n# Search all project dependencies\nmix usage_rules.search_docs \"search term\"\n\n# Search specific packages\nmix usage_rules.search_docs \"search term\" -p ecto -p ash\n\n# Search specific versions\nmix usage_rules.search_docs \"search term\" -p ecto@3.13.2\n\n# Search all packages on hex\nmix usage_rules.search_docs \"search term\" --everywhere\n\n# JSON output\nmix usage_rules.search_docs \"search term\" --output json\n\n# Search only in titles\nmix usage_rules.search_docs \"search term\" --query-by title\n\n# Pagination\nmix usage_rules.search_docs \"search term\" --page 2 --per-page 20\n```\n\n## For Package Authors\n\nEven if you don't use LLMs yourself, your users likely do. Writing a `usage-rules.md` file helps prevent hallucination-driven support requests.\n\nWe 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](https://github.com/ash-project/ash/blob/main/usage-rules.md) for one such large example. Perhaps for your package only a few lines are necessary.\n\nOne 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.\n\nMake sure that your `usage-rules.md` file is included in your hex package's `files` option, so that it is distributed with your package.\n\n### Sub-rules\n\nA package can provide a main `usage-rules.md` and/or sub-rule files:\n\n```\nusage-rules.md          # general rules\nusage-rules/\n  html.md               # html specific rules\n  database.md           # database specific rules\n```\n\n### Migrating from v0.1\n\nv0.2 replaces CLI arguments with project config. If you were running:\n\n```sh\nmix usage_rules.sync AGENTS.md --all --link-to-folder deps\n```\n\nReplace it with config in `mix.exs`:\n\n```elixir\ndef project do\n  [\n    usage_rules: [\n      file: \"AGENTS.md\",\n      usage_rules: :all\n    ]\n  ]\nend\n```\n\nThen just run `mix usage_rules.sync` with no arguments.\n\n### Migrating from v0.2\n\nv1.0 removes `link_to_folder`, `link_style`, and `inline` options. Content is inlined by default. Use per-dep `link` option for linking:\n\n```elixir\n# Before (v0.2)\nusage_rules: :all,\nlink_to_folder: \"deps\",\nlink_style: \"at\",\ninline: [\"usage_rules:all\"]\n\n# After (v1.0)\nusage_rules: [\n  {:ash, link: :at},\n  {:phoenix, link: :at},\n  \"usage_rules:all\"    # inlined by default\n]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fash-project%2Fusage_rules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fash-project%2Fusage_rules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fash-project%2Fusage_rules/lists"}