Search for package-specific usage rules and best practices from Elixir packages. Use when you need coding conventions, patterns, common mistakes, or good/bad examples for packages like Ash, Phoenix, Ecto, etc.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
skills listSkill Instructions
name: usage-rules description: Search for package-specific usage rules and best practices from Elixir packages. Use when you need coding conventions, patterns, common mistakes, or good/bad examples for packages like Ash, Phoenix, Ecto, etc. allowed-tools: Read, Grep, Glob, Bash, AskUserQuestion
Usage Rules Search
Comprehensive search for Elixir and Erlang package usage rules and best practices, following a cascading strategy to find the most relevant coding conventions and patterns.
When to use this skill
Use this skill when you need to:
- Look up coding conventions for a Hex package
- Find best practices and recommended patterns
- See good/bad code examples for proper usage
- Understand common mistakes to avoid
- Learn package-specific idioms and conventions
- Get context-aware recommendations for implementation
Search strategy
This skill implements a cascading search that prioritizes local and contextual information:
- Local dependencies - Search installed packages in
deps/directory for usage-rules.md - Fetched cache - Check previously fetched usage rules in
.usage-rules/ - Progressive fetch - Automatically fetch package and extract usage-rules.md if missing
- Context-aware extraction - Extract relevant sections based on coding context
- Fallback - Note when package doesn't provide usage rules, suggest alternatives
Instructions
Step 1: Identify the package and context
Extract the package name and identify the coding context from the user's question.
Package name examples:
- "Ash best practices" → Package:
ash - "Phoenix LiveView patterns" → Package:
phoenix_live_view - "How to use Ecto properly?" → Package:
ecto
Context keywords:
- Querying: "query", "filter", "search", "find", "list"
- Error handling: "error", "validation", "exception", "handle"
- Actions: "create", "update", "delete", "action", "change"
- Relationships: "relationship", "association", "belongs_to", "has_many"
- Testing: "test", "testing", "mock", "fixture"
- Authorization: "authorization", "permissions", "policy", "access"
- Structure: "structure", "organization", "architecture", "setup"
Step 2: Search local dependencies
Use the Glob and Grep tools to search the deps/ directory for usage rules:
-
Find the package directory with usage-rules.md:
Use Glob: pattern="deps/<package_name>/usage-rules.md"If no results, the package isn't installed locally or doesn't provide usage rules. Skip to Step 3.
-
Check for sub-rules (advanced packages may have specialized rules):
Use Glob: pattern="deps/<package_name>/usage-rules/*.md" -
Search for relevant sections based on context keywords:
Use Grep: pattern="^## (Querying|Error Handling|Actions)", path="deps/<package_name>/usage-rules.md", output_mode="content", -n=trueThis finds section headings with line numbers.
-
Extract relevant sections:
Use Grep: pattern="^## Error Handling", path="deps/<package_name>/usage-rules.md", output_mode="content", -A=50Use
-Aflag to get section content (adjust number based on typical section length). -
Read the complete file if needed for broader context:
Use Read: file_path="deps/<package_name>/usage-rules.md"
Step 3: Check fetched cache and fetch if needed
If the package wasn't found in deps/, check for previously fetched usage rules, or fetch them now.
3.1: Check fetched cache
Use the Glob tool to check if usage rules were previously fetched:
Use Glob: pattern=".usage-rules/<package_name>-*/usage-rules.md"
If found, search the cached rules using the same patterns as Step 2 (sections 3-5).
3.2: Determine version to fetch
If no cached rules found, determine which version to fetch:
-
Check mix.lock for locked version:
Use Bash: grep '"<package_name>"' mix.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' -
Check mix.exs for version constraint:
Use Bash: grep -E '\{:<package_name>' mix.exs | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' -
Get latest version from hex.pm:
Use Bash: curl -s "https://hex.pm/api/packages/<package_name>" | jq -r '.releases[0].version' -
If version ambiguous, use AskUserQuestion to prompt:
Question: "Package '<package_name>' usage rules not found locally. Which version would you like to fetch?" Options: - "Latest (X.Y.Z)" - Fetch most recent release - "Project version (X.Y.Z)" - Use version from mix.exs/mix.lock (if available) - "Specific version" - User provides custom version in "Other" field - "Skip fetching" - Continue without usage rules
3.3: Fetch package and extract usage rules
Once version is determined, fetch the package and extract usage-rules.md:
# Create temp directory and fetch package
mkdir -p .usage-rules/.tmp
mix hex.package fetch <package_name> <version> --unpack --output .usage-rules/.tmp/<package_name>-<version>
# Check if usage-rules.md exists
if [ -f ".usage-rules/.tmp/<package_name>-<version>/usage-rules.md" ]; then
# Create version-specific directory
mkdir -p ".usage-rules/<package_name>-<version>"
# Copy main usage rules file
cp ".usage-rules/.tmp/<package_name>-<version>/usage-rules.md" ".usage-rules/<package_name>-<version>/"
# Copy sub-rules if present
if [ -d ".usage-rules/.tmp/<package_name>-<version>/usage-rules/" ]; then
cp -r ".usage-rules/.tmp/<package_name>-<version>/usage-rules/" ".usage-rules/<package_name>-<version>/"
fi
echo "Usage rules cached in .usage-rules/<package_name>-<version>/"
else
echo "Package does not provide usage-rules.md"
fi
# Clean up temp directory
rm -rf ".usage-rules/.tmp/<package_name>-<version>"
Storage location: .usage-rules/<package_name>-<version>/
If successful:
- Search the cached usage rules using patterns from Step 2
- Read relevant files with the Read tool
If package doesn't include usage-rules.md:
- Package may not have adopted usage rules convention
- Proceed to Step 5 (fallback suggestions)
3.4: Git ignore recommendation
Inform the user that fetched usage rules should be git-ignored. Suggest adding to .gitignore:
# Fetched usage rules
/.usage-rules/
This only needs to be mentioned once per session, and only if fetching actually occurred.
Step 4: Extract relevant sections based on context
Usage rules files can be large (1000+ lines). Extract only relevant sections to avoid context overload.
4.1: Find section headings
# Find all h2 section headings with line numbers
Use Grep: pattern="^## ", path=".usage-rules/<package>-<version>/usage-rules.md", output_mode="content", -n=true
This returns a list like:
7:## Understanding Ash
13:## Code Structure & Organization
21:## Code Interfaces
85:## Actions
120:## Querying Data
4.2: Match context to sections
Based on user's context keywords, identify relevant sections:
Context: "querying" → Look for sections containing:
- "Querying", "Query", "Filters", "Search", "Find"
Context: "error handling" → Look for sections containing:
- "Error", "Validation", "Exception", "Handle"
Context: "actions" → Look for sections containing:
- "Actions", "Create", "Update", "Delete", "CRUD"
4.3: Extract matched sections
# Extract specific section with content
Use Grep: pattern="^## Querying Data", path=".usage-rules/<package>-<version>/usage-rules.md", output_mode="content", -A=80
Adjust -A value based on typical section length:
- Small sections (< 50 lines):
-A=50 - Medium sections (50-150 lines):
-A=100 - Large sections (> 150 lines):
-A=150or read specific ranges
4.4: Include code examples
Look for code blocks within sections:
# Find code examples in section
Use Grep: pattern="```elixir|# GOOD|# BAD", path=".usage-rules/<package>-<version>/usage-rules.md", output_mode="content", -A=10
Code examples often include:
- Good patterns: Marked with
# GOOD,# PREFERRED - Bad patterns: Marked with
# BAD,# AVOID,# WRONG - Inline comments: Explanatory comments in code blocks
Step 5: Present usage rules
Format the output based on what was found.
Output format
When presenting results, organize them as follows:
If found in local dependencies:
Found usage rules for <package_name>:
**Location**: deps/<package_name>/usage-rules.md
**Version**: <version from mix.lock>
**Relevant Best Practices** (<section_name>):
<extracted section content with code examples>
---
**Full Rules**: deps/<package_name>/usage-rules.md
**Integration**: For API documentation, use the hex-docs-search skill.
If found in fetched cache:
Found cached usage rules for <package_name>:
**Version**: <version>
**Cache Location**: .usage-rules/<package>-<version>/usage-rules.md
**Relevant Best Practices** (<section_name>):
<extracted section content with code examples>
---
**Full Rules**: .usage-rules/<package>-<version>/usage-rules.md
**Note**: Rules are cached locally for offline access.
**Integration**: For API documentation, use the hex-docs-search skill.
If usage rules not available:
Package '<package_name>' does not provide usage-rules.md.
**Note**: Usage rules are a community-driven convention where packages provide
best practices in markdown format. Not all packages have adopted this yet.
**Alternatives**:
- Use hex-docs-search skill for API documentation and guides
- Check package README or official documentation
- Search for "<package_name> elixir best practices" online
- Look for community guides and blog posts
**Current packages with usage rules**:
- ash, ash_postgres, ash_json_api (Ash Framework ecosystem)
- igniter, spark, reactor (Build tools and engines)
**Help the ecosystem**: Encourage package maintainers to add usage-rules.md!
If user needs comprehensive guidance:
For comprehensive implementation guidance, use both:
1. **usage-rules skill** - Coding conventions and best practices
2. **hex-docs-search skill** - API documentation and function signatures
Combining both provides complete "how to implement correctly" guidance.
Examples
Example 1: Finding Ash querying best practices
User asks: "What are the best practices for querying data in Ash?"
Search process:
- Extract package:
ash - Identify context: "querying"
- Check
deps/ash/usage-rules.md(found) - Search for section:
## Querying Data - Extract section with code examples
- Present best practices
Output:
Found usage rules for ash:
**Location**: deps/ash/usage-rules.md
**Version**: 3.5.20
**Relevant Best Practices** (Querying Data):
## Querying Data
### Common Query Operations
Prefer using code interface functions with the `query` option for filtering, sorting, and limiting:
```elixir
# PREFERRED - Use the query option
posts = MyApp.Blog.list_posts!(
query: [
filter: [status: :published],
sort: [published_at: :desc],
limit: 10
],
load: [author: :profile]
)
# AVOID - Don't build queries manually outside domain
query = MyApp.Blog.Post
|> Ash.Query.filter(status: :published)
|> Ash.Query.sort(published_at: :desc)
posts = Ash.read!(query)
All query-related options go in the query parameter, not as separate arguments.
Full Rules: deps/ash/usage-rules.md
Integration: For Ecto.Query API documentation, use hex-docs-search skill.
### Example 2: Error handling conventions
**User asks**: "How should I handle errors in Phoenix LiveView?"
**Search process**:
1. Extract package: `phoenix_live_view`
2. Identify context: "error handling"
3. Check `deps/phoenix_live_view/usage-rules.md` (not found - LiveView doesn't provide usage rules yet)
4. Check `.usage-rules/phoenix_live_view-*/usage-rules.md` (not found)
5. Attempt fetch (package doesn't include usage-rules.md)
6. Provide fallback suggestions
**Output**:
Package 'phoenix_live_view' does not provide usage-rules.md.
Alternatives:
- Use hex-docs-search skill for Phoenix.LiveView API documentation
- Check Phoenix LiveView guides: https://hexdocs.pm/phoenix_live_view/
- Search for "phoenix liveview error handling best practices"
Note: Usage rules are a community convention. Help the ecosystem by encouraging package maintainers to add usage-rules.md files!
### Example 3: Unknown package with progressive fetch
**User asks**: "What are the best practices for using Spark DSL?"
**Search process**:
1. Extract package: `spark`
2. Identify context: general (no specific context)
3. Check `deps/spark/usage-rules.md` (not found)
4. Check `.usage-rules/spark-*/usage-rules.md` (not found)
5. Check mix.exs: `{:spark, "~> 2.0"}`
6. Get latest 2.x from hex.pm:
```bash
curl -s "https://hex.pm/api/packages/spark" | jq -r '.releases[] | select(.version | startswith("2.")) | .version' | head -1
# Returns: 2.2.24
- Fetch package:
mix hex.package fetch spark 2.2.24 --unpack --output .usage-rules/.tmp/spark-2.2.24 - Extract usage-rules.md (found!)
- Copy to cache:
.usage-rules/spark-2.2.24/usage-rules.md - Clean up temp
- Read and present usage rules
Output:
Found cached usage rules for spark:
**Version**: 2.2.24
**Cache Location**: .usage-rules/spark-2.2.24/usage-rules.md
**Relevant Best Practices** (Understanding Spark):
## Understanding Spark
Spark is a foundation for declarative DSLs in Elixir. It powers frameworks like Ash
by providing the infrastructure for building expressive, compile-time-validated DSLs.
### Key Concepts
- **Extensions**: Modules that add DSL sections to Spark DSLs
- **Sections**: Top-level DSL constructs (like `actions do ... end`)
- **Entities**: Individual items within sections (like `read :list`)
- **Options**: Configuration for entities
<...more content...>
---
**Full Rules**: .usage-rules/spark-2.2.24/usage-rules.md
**Note**: Rules are now cached locally for offline access.
**Recommendation**: Add `.usage-rules/` to your .gitignore.
Example 4: Cached rules (offline access)
User asks: "Show me Ash relationship best practices again"
Search process:
- Extract package:
ash - Identify context: "relationship"
- Check
deps/ash/usage-rules.md(not found - not in project) - Check
.usage-rules/ash-*/usage-rules.md(found version 3.5.20!) - No fetch needed - use cached rules
- Search for "## Relationships" section
- Extract and present
Result: Fast, offline search without network requests. Works even when disconnected.
Example 5: Context-aware extraction
User asks: "Common mistakes with Ash actions?"
Search process:
- Extract package:
ash - Identify context: "actions" + "mistakes"
- Find usage rules (local or cached)
- Search for "## Actions" section
- Also search for keywords: "mistake", "avoid", "wrong", "bad"
- Extract relevant parts from multiple sections
- Present consolidated best practices
Output:
Found usage rules for ash:
**Relevant Best Practices** (Actions - Common Mistakes):
## Actions
**AVOID** - Don't create generic CRUD actions:
```elixir
# BAD - Generic naming
create :create
update :update
PREFER - Create domain-specific actions:
# GOOD - Specific business operations
create :register_user
update :activate_account
update :suspend_for_violation
AVOID - Don't put business logic outside actions:
# BAD - Logic in controller
def create_post(conn, params) do
{:ok, post} = Blog.create_post(params)
# Business logic here
send_notifications(post)
update_stats()
end
PREFER - Put business logic in action changes:
# GOOD - Logic in action
create :publish_post do
change after_action(fn _changeset, post ->
send_notifications(post)
update_stats()
{:ok, post}
end)
end
Full Rules: deps/ash/usage-rules.md
Tool usage summary
Use Claude's built-in tools in this order:
- Glob - Find usage-rules.md files in deps/, .usage-rules/, and check for sub-rules
- Grep - Search for section headings, context keywords, and code examples
- Read - Read complete usage rules files when broader context needed
- Bash - Fetch packages with mix hex.package, version resolution, extract and cache rules
- AskUserQuestion - Prompt for version when ambiguous
Requirements: curl and jq (Linux/Mac native, use Git Bash or WSL on Windows)
Best practices
- Start local: Always check local dependencies first - they match the version used in the project
- Check cache before fetch: Look for previously fetched rules in
.usage-rules/before fetching - Context-aware extraction: Don't present entire file - extract relevant sections based on keywords
- Show code examples: Always include good/bad pattern examples when available
- Highlight patterns: Point out
# GOODvs# BADcomparisons explicitly - Link to source: Provide file path so users can explore complete rules
- Note integration: Mention hex-docs-search for complementary API documentation
- Git ignore reminder: Mention .gitignore addition once per session when fetching occurs
- Offline capability: Once fetched, usage rules available without network access
- Version awareness: Note which version is installed locally vs fetched from cache
Troubleshooting
Package not found in deps/
- Check
.usage-rules/for previously fetched rules - If not cached, determine version and offer to fetch
- Check if package is in mix.exs dependencies (for version resolution)
- Verify package name spelling (convert
Phoenix.LiveView→phoenix_live_view)
Package doesn't provide usage-rules.md
- This is expected - usage rules are a convention, not all packages have them
- Fallback to hex-docs-search for API documentation
- Suggest checking package README or guides
- Encourage package maintainers to add usage rules
Fetch failures
Package fetch fails:
- Verify package name spelling
- Check network connectivity
- Verify package exists on hex.pm
- Try web search as fallback
Extraction fails:
- Package was fetched but doesn't include usage-rules.md
- Clean up temp directory
- Note that package doesn't provide rules
Cache location issues
Fetched rules not found on repeat queries:
- Verify
.usage-rules/directory exists - Check that fetch command completed successfully
- May need to re-fetch if directories were deleted
- Ensure temp cleanup didn't remove permanent cache
Section extraction challenges
Section too large:
- Increase
-Avalue in Grep to get more content - Or read complete file and extract programmatically
- Consider showing summary + offering full section
Multiple relevant sections:
- Extract multiple sections
- Present them in logical order
- Clearly label each section
No section matches context:
- Show "## Understanding [Package]" section as default
- List available sections for user to choose from
- Read complete file if user wants comprehensive overview
Version mismatches
Different version in deps/ vs cache:
- Prefer deps/ version (matches project)
- Note version difference if using cache
- Offer to fetch version matching project dependencies
Version specified doesn't exist:
- List available versions from hex.pm
- Prompt user to select valid version
- Fall back to latest if user unsure
More by bradleygolden
View allGenerate project-specific workflow commands (research, plan, implement, qa) by asking questions about the project and creating customized commands
Research Hex packages (Sobelow, Phoenix, Ecto, Credo, Ash, etc). Use when investigating packages, understanding integration patterns, or finding module/function docs and usage examples. Automatically fetches missing documentation and source code locally.