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.
/plugin marketplace add bradleygolden/claude-marketplace-elixir/plugin install core@elixirThis skill is limited to using the following tools:
README.mdComprehensive search for Elixir and Erlang package usage rules and best practices, following a cascading strategy to find the most relevant coding conventions and patterns.
Use this skill when you need to:
This skill implements a cascading search that prioritizes local and contextual information:
deps/ directory for usage-rules.md.usage-rules/Extract the package name and identify the coding context from the user's question.
Package name examples:
ashphoenix_live_viewectoContext keywords:
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=true
This 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=50
Use -A flag 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"
If the package wasn't found in deps/, check for previously fetched usage rules, or fetch them now.
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).
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
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:
If package doesn't include usage-rules.md:
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.
Usage rules files can be large (1000+ lines). Extract only relevant sections to avoid context overload.
# 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
Based on user's context keywords, identify relevant sections:
Context: "querying" → Look for sections containing:
Context: "error handling" → Look for sections containing:
Context: "actions" → Look for sections containing:
# 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:
-A=50-A=100-A=150 or read specific rangesLook 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, # PREFERRED# BAD, # AVOID, # WRONGFormat the output based on what was found.
When presenting results, organize them as follows:
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.
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.
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!
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.
User asks: "What are the best practices for querying data in Ash?"
Search process:
ashdeps/ash/usage-rules.md (found)## Querying DataOutput:
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:
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
mix hex.package fetch spark 2.2.24 --unpack --output .usage-rules/.tmp/spark-2.2.24
.usage-rules/spark-2.2.24/usage-rules.mdOutput:
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.
User asks: "Show me Ash relationship best practices again"
Search process:
ashdeps/ash/usage-rules.md (not found - not in project).usage-rules/ash-*/usage-rules.md (found version 3.5.20!)Result: Fast, offline search without network requests. Works even when disconnected.
User asks: "Common mistakes with Ash actions?"
Search process:
ashOutput:
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
Use Claude's built-in tools in this order:
Requirements: curl and jq (Linux/Mac native, use Git Bash or WSL on Windows)
.usage-rules/ before fetching# GOOD vs # BAD comparisons explicitly.usage-rules/ for previously fetched rulesPhoenix.LiveView → phoenix_live_view)Package fetch fails:
Extraction fails:
Fetched rules not found on repeat queries:
.usage-rules/ directory existsSection too large:
-A value in Grep to get more contentMultiple relevant sections:
No section matches context:
Different version in deps/ vs cache:
Version specified doesn't exist:
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.