commit 846fe14759bc32cfd19cfc3f586ed2c2a715ec96 Author: Zhongwei Li Date: Sat Nov 29 18:02:05 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..647e46c --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "core", + "description": "Essential Elixir development support with hooks and automation", + "version": "1.2.2", + "author": { + "name": "Bradley Golden", + "url": "https://github.com/bradleygolden" + }, + "skills": [ + "./skills" + ], + "hooks": [ + "./hooks" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..493c56e --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# core + +Essential Elixir development support with hooks and automation diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 0000000..c08fd71 --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,53 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/auto-format.sh", + "timeout": 15 + }, + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/compile-check.sh", + "timeout": 20 + } + ] + }, + { + "matcher": "Read", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/recommend-docs-on-read.sh" + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/pre-commit-check.sh", + "timeout": 45 + } + ] + } + ], + "UserPromptSubmit": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/recommend-docs-lookup.sh" + } + ] + } + ] + } +} diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..ec2372b --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,61 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:bradleygolden/claude-marketplace-elixir:plugins/core", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "b4ddf33811ea1d3bb8a65e22ebafd0f88d641698", + "treeHash": "57d924a1542767fa6b4f5b0528ba0c40dbcc2a8af681129a25e109ee00c79e83", + "generatedAt": "2025-11-28T10:14:21.944320Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "core", + "description": "Essential Elixir development support with hooks and automation", + "version": "1.2.2" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "a6d4920c1a411d59014d2f965899c5bf362316f6837dd4e6c852c59c4ea05883" + }, + { + "path": "hooks/hooks.json", + "sha256": "dce89d1c71af6b825d017165c9e8c2a6ca99d891466b60b15bdca984d8e3eddd" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "e65cc4c9eff4b0acfd843737ed74bff2df69797b42bd7e1a3a9144323ffe215c" + }, + { + "path": "skills/usage-rules/README.md", + "sha256": "13dfeaf6422fd6cb018f799ecef090d55b64d4bc9e36e05de0407b3fd64f4f34" + }, + { + "path": "skills/usage-rules/SKILL.md", + "sha256": "e9205b8dcc85df67e6104e8a423dae3c2976608a818e9a7c6c7d0b5a676c2b41" + }, + { + "path": "skills/hex-docs-search/README.md", + "sha256": "466e1fd9da8fa9ff804a83bdf407b109d69d4800d1ffc4ae07adda1f4a772e90" + }, + { + "path": "skills/hex-docs-search/SKILL.md", + "sha256": "c68bace1cf350be541a797f09debf1236334db27b94396f184fd1c7f421c58a1" + } + ], + "dirSha256": "57d924a1542767fa6b4f5b0528ba0c40dbcc2a8af681129a25e109ee00c79e83" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/hex-docs-search/README.md b/skills/hex-docs-search/README.md new file mode 100644 index 0000000..995c699 --- /dev/null +++ b/skills/hex-docs-search/README.md @@ -0,0 +1,155 @@ +# Hex Docs Search Skill + +A comprehensive skill for searching Elixir and Erlang package documentation using a cascading search strategy. + +## Overview + +This skill helps Claude search for Hex package documentation intelligently by: +1. First checking local dependencies in `deps/` +2. Then checking previously fetched documentation and source in `.hex-docs/` and `.hex-packages/` +3. Automatically fetching missing documentation or source code when needed (with version prompting) +4. Searching the codebase for real usage examples +5. Querying the hex.pm API for official docs +6. Falling back to web search if needed + +## Usage + +This skill is automatically available when the `core@elixir` plugin is installed. Claude will use it when appropriate, for example: + +``` +User: "How do I use Phoenix.LiveView mount/3?" +User: "Show me Ecto.Query examples" +User: "What does Jason.decode!/1 do?" +User: "Research the Sobelow hex package" +User: "Learn about the Credo library" +User: "Understand how Ash Framework works" +``` + +## How it Works + +### 1. Local Dependencies Search (deps/) + +Uses Grep and Glob tools to search installed packages for BOTH code and docs: +- **Source code**: Finds module definitions, function implementations, and `@moduledoc`/`@doc` annotations +- **Generated docs**: Checks for HTML documentation in `deps/*/doc/` directories +- Provides full context from whichever source is most helpful + +**Advantage**: Matches the exact version used in the project + +### 2. Fetched Cache Search (.hex-docs/ and .hex-packages/) + +Checks for previously fetched documentation and source code: +- **Documentation**: Searches `.hex-docs/docs/hexpm///` for HTML docs +- **Source code**: Searches `.hex-packages/-/` for unpacked source +- Uses same search patterns as deps/ directory + +**Advantage**: Fast, offline-capable access to packages not in project dependencies + +### 3. Progressive Fetch (NEW) + +When packages aren't found locally, automatically fetches them: +- **Version detection**: Checks mix.lock, mix.exs, or hex.pm for version +- **User prompting**: Asks user to choose version when ambiguous (latest vs specific) +- **Documentation first**: Fetches HTML docs with `mix hex.docs fetch` to `.hex-docs/` +- **Source if needed**: Fetches source code with `mix hex.package fetch --unpack` to `.hex-packages/` +- **Cached for future**: All fetched content reusable in subsequent queries + +**Advantage**: Builds a local knowledge base of documentation and source code over time + +### 4. Codebase Usage Search + +Searches the project's `lib/` and `test/` directories: +- Finds `alias` and `import` statements +- Locates function calls +- Shows real-world usage from your code + +**Advantage**: Context-aware examples from your actual codebase + +### 5. HexDocs Search API + +Uses the HexDocs search API at `https://search.hexdocs.pm/`: +- Full-text search across documentation content +- Filters by package name and version +- Returns documentation excerpts with direct links +- Falls back to hex.pm API for package info + +**Advantage**: Searches actual documentation content, not just package metadata + +### 6. Web Search Fallback + +Uses WebSearch with targeted queries: +- `site:hexdocs.pm ` for specific docs +- General Elixir documentation search + +**Advantage**: Finds community examples and guides + +## Examples + +### Example 1: Looking up a commonly used dependency + +``` +User: "How do I query with Ecto?" + +Claude will: +1. Find deps/ecto/lib/ecto/query.ex +2. Search for "import Ecto.Query" in lib/ +3. Show usage examples from the project +4. Read @moduledoc from the source +``` + +### Example 2: Unknown package with progressive fetch + +``` +User: "What is the Timex library?" + +Claude will: +1. Check deps/timex (not found) +2. Check .hex-docs/docs/hexpm/timex/ (not found) +3. Detect no version in project dependencies +4. Query hex.pm for latest version +5. Prompt: "Fetch latest (3.7.11) or specific version?" +6. User selects "Latest" +7. Fetch: HEX_HOME=.hex-docs mix hex.docs fetch timex 3.7.11 +8. Search fetched HTML documentation +9. Present findings with link to cached docs +10. Suggest adding to .gitignore if not present + +Future queries: Instant access to cached documentation +``` + +### Example 3: Specific function lookup + +``` +User: "How does Jason.decode!/2 work?" + +Claude will: +1. Find deps/jason/lib/jason.ex +2. Grep for "def decode!" +3. Show the @doc and implementation +4. Find usage in tests/ +``` + +## Requirements + +- `curl` - For hex.pm API queries +- `jq` - For JSON parsing (recommended) +- `mix` - For fetching packages and documentation +- Internet access - For API, web search, and fetching packages/docs + +## Recommended .gitignore Entries + +Add these to your `.gitignore` to exclude fetched content: + +```gitignore +# Fetched Hex documentation and packages +/.hex-docs/ +/.hex-packages/ +``` + +These directories can be large and are easily re-fetched on demand. + +## Integration + +This skill is bundled with the `core@elixir` plugin and doesn't require separate installation. + +See [SKILL.md](SKILL.md) for the complete skill prompt and instructions. diff --git a/skills/hex-docs-search/SKILL.md b/skills/hex-docs-search/SKILL.md new file mode 100644 index 0000000..66ac055 --- /dev/null +++ b/skills/hex-docs-search/SKILL.md @@ -0,0 +1,457 @@ +--- +name: hex-docs-search +description: 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. +allowed-tools: Read, Grep, Glob, Bash, WebSearch, AskUserQuestion +--- + +# Hex Documentation Search + +Comprehensive search for Elixir and Erlang package documentation, following a cascading strategy to find the most relevant and context-aware information. + +## When to use this skill + +Use this skill when you need to: +- Look up documentation for a Hex package or dependency +- Find function signatures, module documentation, or type specs +- See usage examples of a library or module +- Understand how a dependency is used in the current project +- Search for Elixir/Erlang standard library documentation + +## Search strategy + +This skill implements a **cascading search** that prioritizes local and contextual information: + +1. **Local dependencies** - Search installed packages in `deps/` directory (both source code AND generated docs) +2. **Fetched cache** - Check previously fetched documentation and source code in `.hex-docs/` and `.hex-packages/` +3. **Progressive fetch** - Automatically fetch missing documentation or source code locally when needed +4. **Codebase usage** - Find how packages are used in the current project +5. **HexDocs API** - Search official documentation on hexdocs.pm (fallback) +6. **Web search** - Fallback to general web search (last resort) + +## Instructions + +### Step 1: Identify the search target + +Extract the package name and optionally the module or function name from the user's question. + +Examples: +- "How do I use Phoenix.LiveView?" → Package: `phoenix_live_view`, Module: `Phoenix.LiveView` +- "Show me Ecto query examples" → Package: `ecto`, Module: `Ecto.Query` +- "What does Jason.decode!/1 do?" → Package: `jason`, Module: `Jason`, Function: `decode!` + +### Step 2: Search local dependencies + +Use the **Glob** and **Grep** tools to search the `deps/` directory for BOTH code and documentation: + +1. **Find the package directory**: + ``` + Use Glob: pattern="deps//**/*.ex" + ``` + + If no results, the package isn't installed locally. Skip to Step 4. + +2. **Search for module definition in source code**: + ``` + Use Grep: pattern="defmodule ", path="deps//lib" + ``` + +3. **Search for function definition in source code** (if looking for specific function): + ``` + Use Grep: pattern="def ", path="deps//lib", output_mode="content", -A=5 + ``` + +4. **Find documentation in source code** (@moduledoc/@doc annotations): + ``` + Use Grep: pattern="@moduledoc|@doc", path="deps//lib", output_mode="content", -A=10 + ``` + +5. **Check for generated HTML documentation** (if available): + ``` + Use Glob: pattern="deps//doc/**/*.html" + ``` + + If HTML docs exist, search them for relevant content: + ``` + Use Grep: pattern="|", path="deps//doc" + ``` + +6. **Read the relevant files** using the Read tool to get full context from either source or HTML docs. + +### Step 3: Check fetched cache and fetch if needed + +If the package wasn't found in `deps/`, check for previously fetched documentation or source code, or fetch it now. + +#### 3.1: Check fetched documentation cache + +Use the **Glob** tool to check if documentation was previously fetched: + +``` +Use Glob: pattern=".hex-docs/docs/hexpm//*/*.html" +``` + +If found, search the fetched documentation using the same patterns as Step 2 (sections 5 and 6). + +#### 3.2: Check fetched source code cache + +Use the **Glob** tool to check if source code was previously fetched: + +``` +Use Glob: pattern=".hex-packages/-*/**/*.ex" +``` + +If found, search the fetched source using the same patterns as Step 2 (sections 2-4). + +#### 3.3: Determine version to fetch + +If no cached docs or source found, determine which version to fetch: + +1. **Check mix.lock** for locked version: + ``` + Use Bash: grep '""' mix.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' + ``` + +2. **Check mix.exs** for version constraint: + ``` + Use Bash: grep -E '\{:' mix.exs | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' + ``` + +3. **Get latest version from hex.pm**: + ``` + Use Bash: curl -s "https://hex.pm/api/packages/" | jq -r '.releases[0].version' + ``` + +4. **If version ambiguous**, use **AskUserQuestion** to prompt: + ``` + Question: "Package '' 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 to HexDocs API search without fetching + ``` + +#### 3.4: Progressive fetch (documentation first) + +Once version is determined, fetch documentation to project-local cache: + +```bash +# Use custom HEX_HOME to store in project directory +HEX_HOME=.hex-docs mix hex.docs fetch +``` + +**Storage location**: `.hex-docs/docs/hexpm///` + +If successful: +- Search the fetched HTML documentation using patterns from Step 2 (sections 5-6) +- Read relevant files with the Read tool + +If **documentation fetch fails** (package has no docs) or **docs lack sufficient detail**: +- Proceed to Step 3.5 to fetch source code + +#### 3.5: Fetch source code if needed + +If documentation is insufficient or unavailable, fetch package source code: + +```bash +# Fetch and unpack to project-local directory +mix hex.package fetch --unpack --output .hex-packages/- +``` + +**Storage location**: `.hex-packages/-/` + +If successful: +- Search the source code using patterns from Step 2 (sections 2-4) +- Read source files with the Read tool +- Examine @moduledoc and @doc annotations + +If **source fetch fails**: +- Continue to Step 5 (HexDocs API search) as fallback + +#### 3.6: Git ignore recommendation + +Inform the user that fetched content should be git-ignored. Suggest adding to `.gitignore`: + +```gitignore +# Fetched Hex documentation and packages +/.hex-docs/ +/.hex-packages/ +``` + +This only needs to be mentioned once per session, and only if fetching actually occurred. + +### Step 4: Search codebase usage + +Use the **Grep** tool to find usage patterns in the current project: + +1. **Find imports and aliases**: + ``` + Use Grep: pattern="alias |import ", path="lib", output_mode="content", -n=true + ``` + +2. **Find function calls**: + ``` + Use Grep: pattern="\.", path="lib", output_mode="content", -A=3 + ``` + +3. **Search test files for examples**: + ``` + Use Grep: pattern="", path="test", output_mode="content", -A=5 + ``` + +This provides **real-world usage examples** from the current project, which is often the most helpful context. + +### Step 5: Search HexDocs Search API + +If local search doesn't provide sufficient information, use the **Bash** tool to search the HexDocs search API. + +**Full-text search across documentation:** + +```bash +# Search across all packages +curl -s "https://search.hexdocs.pm/?q=&query_by=doc,title" | jq -r '.found, .hits[0:5][] | .document | "\(.package) - \(.title)\n\(.doc)\n---"' + +# Search within a specific package (get version first) +VERSION=$(curl -s "https://hex.pm/api/packages/" | jq -r '.releases[0].version') +curl -s "https://search.hexdocs.pm/?q=&query_by=doc,title&filter_by=package:=[-$VERSION]" | jq -r '.hits[] | .document | "\(.title)\n\(.doc)\nURL: https://hexdocs.pm\(.url)\n---"' +``` + +**Examples:** + +```bash +# Search for "mount" in phoenix_live_view +VERSION=$(curl -s "https://hex.pm/api/packages/phoenix_live_view" | jq -r '.releases[0].version') +curl -s "https://search.hexdocs.pm/?q=mount&query_by=doc,title&filter_by=package:=[phoenix_live_view-$VERSION]" | jq -r '.hits[0:3][] | .document | "\(.title)\n\(.doc)\n---"' + +# General search for Ecto.Query +curl -s "https://search.hexdocs.pm/?q=Ecto.Query&query_by=doc,title" | jq -r '.hits[0:5][] | .document | "\(.package) - \(.title)\n\(.doc)\n"' +``` + +**API Response structure:** +- `found`: Total number of results +- `hits[]`: Array of results with: + - `document.package`: Package name + - `document.ref`: Version + - `document.title`: Function/module name + - `document.doc`: Documentation text + - `document.url`: Path to docs (append to https://hexdocs.pm) + +**Requirements:** curl and jq (available on Linux/Mac, use Git Bash or WSL on Windows) + +### Step 6: Web search fallback + +If the above steps don't provide sufficient information, use the **WebSearch** tool: + +First try searching hexdocs.pm specifically: +``` +Use WebSearch: query="site:hexdocs.pm " +``` + +If that doesn't help, do a general search: +``` +Use WebSearch: query="elixir documentation examples" +``` + +## Output format + +When presenting results, organize them as follows: + +### If found locally: + +``` +Found in local dependencies: + +**Location**: deps/ +**Version**: + +**Documentation**: + + +**Usage in this project**: + +``` + +### If found on HexDocs: + +``` +Found on HexDocs: + +**Package**: +**Latest version**: +**Documentation**: https://hexdocs.pm///.html + + +``` + +### If using web search: + +``` +Searching web for documentation: + + +``` + +## Examples + +### Example 1: Finding Phoenix.LiveView documentation + +**User asks**: "How do I use Phoenix.LiveView mount/3?" + +**Search process**: +1. Check `deps/phoenix_live_view/` exists +2. Search for `def mount` in `deps/phoenix_live_view/lib/` (source code) +3. Read the `@doc` annotation for `mount/3` from source +4. Check for HTML docs in `deps/phoenix_live_view/doc/` and read if available +5. Search project for `mount` implementations in `lib/*/live/*.ex` (usage examples) +6. Show documentation and examples from both deps and codebase + +### Example 2: Looking up Ecto.Query + +**User asks**: "Show me Ecto.Query examples" + +**Search process**: +1. Check `deps/ecto/` for source code +2. Search project for `import Ecto.Query` +3. Find query examples in `lib/*/queries/*.ex` or `lib/*_context.ex` +4. If needed, search HexDocs API: + ```bash + curl -s "https://search.hexdocs.pm/?q=Ecto.Query&query_by=doc,title" | jq '.hits[0:3]' + ``` +5. Show local examples first, then external docs + +### Example 3: Unknown package with progressive fetch + +**User asks**: "How do I use the Timex library?" + +**Search process**: +1. Check `deps/timex/` (not found) +2. Check `.hex-docs/docs/hexpm/timex/` (not found) +3. Check `.hex-packages/timex-*/` (not found) +4. Check mix.exs/mix.lock (not in project dependencies) +5. Get latest version from hex.pm: + ```bash + curl -s "https://hex.pm/api/packages/timex" | jq -r '.releases[0].version' + # Returns: 3.7.11 + ``` +6. Prompt user: "Package 'timex' not found locally. Fetch latest (3.7.11)?" +7. User confirms: "Latest" +8. Fetch documentation: + ```bash + HEX_HOME=.hex-docs mix hex.docs fetch timex 3.7.11 + # Stores in: .hex-docs/docs/hexpm/timex/3.7.11/ + ``` +9. Search fetched HTML documentation +10. If docs sufficient, present findings +11. If docs lack detail, offer to fetch source: + ```bash + mix hex.package fetch timex 3.7.11 --unpack --output .hex-packages/timex-3.7.11 + ``` +12. Search source code for implementation details +13. Suggest adding to .gitignore if not already present +14. Offer to add it to mix.exs if user wants to use it + +**Future queries**: Documentation and source cached locally for instant offline access + +### Example 4: Cached documentation (offline-capable) + +**User asks**: "Show me Phoenix.LiveView.mount/3 again" + +**Search process**: +1. Check `deps/phoenix_live_view/` (not found) +2. Check `.hex-docs/docs/hexpm/phoenix_live_view/` (found version 0.20.0!) +3. **No fetch needed** - use cached documentation +4. Search cached HTML: `.hex-docs/docs/hexpm/phoenix_live_view/0.20.0/Phoenix.LiveView.html` +5. Present documentation instantly + +**Result**: Fast, offline search without network requests. Works even when disconnected. + +### Example 5: Progressive fetch (docs → source) + +**User asks**: "Show me the implementation of Jason.decode!/2" + +**Search process**: +1. Check `deps/jason/` (not found) +2. Check `.hex-docs/docs/hexpm/jason/` (not found) +3. Check project version in mix.exs: `{:jason, "~> 1.4"}` +4. Resolve to latest 1.4.x from hex.pm: 1.4.4 +5. Fetch docs: + ```bash + HEX_HOME=.hex-docs mix hex.docs fetch jason 1.4.4 + ``` +6. Search docs: Find signature but not implementation details +7. Offer: "Documentation shows the signature. Fetch source code for implementation?" +8. User confirms +9. Fetch source: + ```bash + mix hex.package fetch jason 1.4.4 --unpack --output .hex-packages/jason-1.4.4 + ``` +10. Search source: `.hex-packages/jason-1.4.4/lib/jason.ex` +11. Present implementation with line numbers + +**Result**: Both docs and source cached for comprehensive future queries + +## Tool usage summary + +Use Claude's built-in tools in this order: + +1. **Glob** - Find package files in deps/, .hex-docs/, and .hex-packages/ +2. **Grep** - Search for modules, functions, and documentation in deps/, fetched cache, and project code +3. **Read** - Read full files for detailed documentation +4. **Bash** - Fetch packages/docs with mix hex commands; Query HexDocs Search API with curl + jq +5. **AskUserQuestion** - Prompt for version when ambiguous +6. **WebSearch** - Fallback search for hexdocs.pm or general web + +**Requirements:** curl and jq (Linux/Mac native, use Git Bash or WSL on Windows) + +## Best practices + +1. **Start local**: Always check local dependencies first - they match the version used in the project +2. **Check cache before fetch**: Look for previously fetched docs/source in `.hex-docs/` and `.hex-packages/` before fetching +3. **Progressive fetch**: Try documentation first (lighter, faster), then source if needed +4. **Prompt for clarity**: Always prompt for version when ambiguous - don't assume latest is desired +5. **Show usage**: Real code examples from the current project are more valuable than generic documentation +6. **Version awareness**: Note which version is installed locally vs latest on hex.pm vs fetched +7. **Progressive disclosure**: Start with a summary, offer to dive deeper if needed +8. **Link to source**: Provide file paths (with line numbers) so users can explore further +9. **Git ignore reminder**: Mention .gitignore addition once per session when fetching occurs +10. **Offline capability**: Once fetched, documentation and source available without network access + +## Troubleshooting + +### Package not found in deps/ + +- Check `.hex-docs/` and `.hex-packages/` for previously fetched content +- If not cached, determine version and offer to fetch +- Check if it's in mix.exs dependencies (for version resolution) +- Suggest running `mix deps.get` if it should be a project dependency +- Search hex.pm to verify the package exists + +### Fetch failures + +**Documentation fetch fails**: +- Package may not have published docs (some packages only have source) +- Offer to fetch source code instead +- Fall back to HexDocs API search + +**Source fetch fails**: +- Verify package name spelling +- Check network connectivity +- Fall back to HexDocs API search + +### Cache location issues + +**Fetched content not found on repeat queries**: +- Verify `.hex-docs/` and `.hex-packages/` directories exist +- Check that fetch commands completed successfully +- May need to re-fetch if directories were deleted + +### No documentation in deps/ + +- Some packages don't include @doc annotations +- Fall back to hexdocs.pm search +- Read the source code directly and explain it + +### HexDocs API rate limiting + +- If the API is rate limited, fall back to web search +- Cache results when possible +- Use web search with `site:hexdocs.pm` filter diff --git a/skills/usage-rules/README.md b/skills/usage-rules/README.md new file mode 100644 index 0000000..8e6aef1 --- /dev/null +++ b/skills/usage-rules/README.md @@ -0,0 +1,249 @@ +# Usage Rules Search Skill + +A comprehensive skill for searching Elixir and Erlang package usage rules and best practices using a cascading strategy. + +## Overview + +This skill helps Claude search for package usage rules intelligently by: +1. **Local dependencies** - Searches installed packages in `deps/` directory +2. **Fetched cache** - Checks previously fetched usage rules in `.usage-rules/` +3. **Progressive fetch** - Automatically fetches missing usage rules when needed +4. **Context-aware extraction** - Extracts relevant sections based on coding context +5. **Fallback guidance** - Provides alternatives when rules unavailable + +## Usage + +This skill is automatically available when the `core@elixir` plugin is installed. Claude will use it when appropriate, for example: + +``` +User: "What are Ash best practices for querying?" +User: "Show me error handling patterns in Phoenix" +User: "How should I structure Ecto schemas?" +User: "What are common mistakes with LiveView?" +User: "Best practices for Ash relationships" +``` + +## How it Works + +### 1. Local Dependencies Search (deps/) + +Searches installed packages for `usage-rules.md` files: +- Finds usage rules matching your project's version +- Searches for relevant sections based on context +- Extracts code examples with good/bad patterns + +**Advantage**: Matches the exact version used in the project + +### 2. Fetched Cache Search (.usage-rules/) + +Checks for previously fetched usage rules: +- Searches `.usage-rules/-/usage-rules.md` +- Includes sub-rules if package provides them +- Uses same search patterns as deps/ + +**Advantage**: Fast, offline-capable access to packages not in project dependencies + +### 3. Progressive Fetch + +When usage rules aren't found locally, automatically fetches them: +- **Version detection**: Checks mix.lock, mix.exs, or hex.pm for version +- **User prompting**: Asks user to choose version when ambiguous (latest vs specific) +- **Package fetch**: Downloads package with `mix hex.package fetch` +- **Extraction**: Copies usage-rules.md to `.usage-rules/-/` +- **Cached for future**: All fetched rules reusable in subsequent queries + +**Advantage**: Builds a local knowledge base of usage rules over time + +### 4. Context-Aware Extraction + +Extracts relevant sections based on what you're working on: +- **Querying** → "## Querying Data" section +- **Error handling** → "## Error Handling" section +- **Actions** → "## Actions" section +- **Relationships** → "## Relationships" section +- **Testing** → "## Testing" section + +**Advantage**: Focused guidance without overwhelming context + +### 5. Fallback Guidance + +When package doesn't provide usage rules: +- Notes that package hasn't adopted convention +- Suggests using hex-docs-search for API documentation +- Recommends checking package README or guides +- Lists packages that currently have usage rules + +**Advantage**: Graceful handling of unavailable rules + +## Examples + +### Example 1: Looking up Ash querying best practices + +``` +User: "What are Ash best practices for querying?" + +Claude will: +1. Find deps/ash/usage-rules.md or .usage-rules/ash-*/usage-rules.md +2. Extract "## Querying Data" section +3. Show code examples with GOOD/BAD patterns +4. Provide file path for full rules +``` + +### Example 2: Unknown package with progressive fetch + +``` +User: "What are Spark DSL best practices?" + +Claude will: +1. Check deps/spark/usage-rules.md (not found) +2. Check .usage-rules/spark-*/usage-rules.md (not found) +3. Detect version from mix.exs or query hex.pm +4. Prompt: "Fetch Spark 2.2.24 usage rules?" +5. User confirms: "Latest" +6. Fetch: mix hex.package fetch spark 2.2.24 --unpack +7. Extract: .usage-rules/spark-2.2.24/usage-rules.md +8. Present usage rules with relevant sections +9. Suggest adding to .gitignore + +Future queries: Instant access to cached rules +``` + +### Example 3: Cached rules (offline access) + +``` +User: "Show me Ash relationship best practices again" + +Claude will: +1. Check deps/ash/usage-rules.md (not found) +2. Check .usage-rules/ash-*/usage-rules.md (found version 3.5.20!) +3. **No fetch needed** - use cached rules +4. Extract "## Relationships" section +5. Present instantly + +Result: Fast, offline search without network requests +``` + +### Example 4: Package without usage rules + +``` +User: "Phoenix LiveView best practices?" + +Claude will: +1. Check for usage rules (not found) +2. Note that LiveView doesn't provide usage-rules.md yet +3. Suggest alternatives: + - Use hex-docs-search for API documentation + - Check Phoenix LiveView guides + - Search web for community practices +``` + +### Example 5: Context-aware extraction + +``` +User: "Common mistakes with Ash actions?" + +Claude will: +1. Find Ash usage rules +2. Identify context: "actions" + "mistakes" +3. Extract "## Actions" section +4. Search for keywords: "mistake", "avoid", "bad", "wrong" +5. Present consolidated best practices with patterns to avoid +``` + +## Requirements + +- `curl` - For hex.pm API queries +- `jq` - For JSON parsing +- `mix` - For fetching packages + +These are standard on Linux/Mac, use Git Bash or WSL on Windows. + +## Recommended .gitignore Entries + +Add these to your `.gitignore` to exclude fetched usage rules: + +```gitignore +# Fetched usage rules +/.usage-rules/ +``` + +These directories can be large and are easily re-fetched on demand. + +## Integration with hex-docs-search + +This skill focuses on **coding conventions and best practices**. For **API documentation** (function signatures, parameters, return values), use the **hex-docs-search** skill. + +**Comprehensive guidance**: Agents can invoke both skills to provide complete "how to use it correctly" guidance: +- **usage-rules**: Conventions, patterns, good/bad examples +- **hex-docs-search**: API documentation, function signatures + +**Example**: +``` +User: "Help me implement Ash queries properly" + +Agent combines both: +1. usage-rules: Get Ash querying conventions (use code interfaces, avoid manual queries) +2. hex-docs-search: Get Ecto.Query API documentation (filter operators, query functions) +3. Synthesize: "Here's how to do it (conventions) + what's available (API)" +``` + +## Current Usage Rules Availability + +**Packages with usage rules** (as of 2025-10-31): +- **Ash ecosystem**: ash, ash_postgres, ash_json_api +- **Build tools**: igniter, spark, reactor + +**Note**: Usage rules are a community-driven convention. Not all packages have adopted this yet, but adoption is growing. + +**Help the ecosystem**: Encourage package maintainers to add `usage-rules.md` files! These files help both humans and AI understand best practices. + +## What are Usage Rules? + +Usage rules are **LLM-optimized markdown files** (`usage-rules.md`) that packages provide to guide proper usage: + +**Characteristics**: +- Located at package root: `/usage-rules.md` +- Dense, token-efficient format +- Code-first with good/bad examples +- Organized by topic (querying, error handling, testing, etc.) +- Includes inline comments and quick references + +**Example structure**: +```markdown +# Rules for working with Ash + +## Understanding Ash +[High-level overview] + +## Code Structure & Organization +[Conventions for organizing code] + +## Querying Data +```elixir +# GOOD - Use code interface +MyApp.Blog.list_posts!(query: [filter: [status: :published]]) + +# BAD - Don't bypass domain +Ash.Query.filter(MyApp.Blog.Post, status: :published) |> Ash.read!() +``` +``` + +## How to Create Usage Rules + +If you're a package maintainer: + +1. Create `usage-rules.md` in your package root +2. Start with "# Rules for working with [Package]" +3. Add "## Understanding [Package]" section (overview) +4. Organize by common tasks and features +5. Use code examples with `# GOOD` and `# BAD` patterns +6. Keep it dense and token-efficient +7. Include in your hex package `files` list + +See [Ash's usage-rules.md](https://github.com/ash-project/ash/blob/main/usage-rules.md) for a comprehensive example. + +## Integration + +This skill is bundled with the `core@elixir` plugin and doesn't require separate installation. + +See [SKILL.md](SKILL.md) for the complete skill prompt and instructions. diff --git a/skills/usage-rules/SKILL.md b/skills/usage-rules/SKILL.md new file mode 100644 index 0000000..d9c21e3 --- /dev/null +++ b/skills/usage-rules/SKILL.md @@ -0,0 +1,624 @@ +--- +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: + +1. **Local dependencies** - Search installed packages in `deps/` directory for usage-rules.md +2. **Fetched cache** - Check previously fetched usage rules in `.usage-rules/` +3. **Progressive fetch** - Automatically fetch package and extract usage-rules.md if missing +4. **Context-aware extraction** - Extract relevant sections based on coding context +5. **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: + +1. **Find the package directory with usage-rules.md**: + ``` + Use Glob: pattern="deps//usage-rules.md" + ``` + + If no results, the package isn't installed locally or doesn't provide usage rules. Skip to Step 3. + +2. **Check for sub-rules** (advanced packages may have specialized rules): + ``` + Use Glob: pattern="deps//usage-rules/*.md" + ``` + +3. **Search for relevant sections** based on context keywords: + ``` + Use Grep: pattern="^## (Querying|Error Handling|Actions)", path="deps//usage-rules.md", output_mode="content", -n=true + ``` + + This finds section headings with line numbers. + +4. **Extract relevant sections**: + ``` + Use Grep: pattern="^## Error Handling", path="deps//usage-rules.md", output_mode="content", -A=50 + ``` + + Use `-A` flag to get section content (adjust number based on typical section length). + +5. **Read the complete file** if needed for broader context: + ``` + Use Read: file_path="deps//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/-*/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: + +1. **Check mix.lock** for locked version: + ``` + Use Bash: grep '""' mix.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' + ``` + +2. **Check mix.exs** for version constraint: + ``` + Use Bash: grep -E '\{:' mix.exs | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' + ``` + +3. **Get latest version from hex.pm**: + ``` + Use Bash: curl -s "https://hex.pm/api/packages/" | jq -r '.releases[0].version' + ``` + +4. **If version ambiguous**, use **AskUserQuestion** to prompt: + ``` + Question: "Package '' 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: + +```bash +# Create temp directory and fetch package +mkdir -p .usage-rules/.tmp +mix hex.package fetch --unpack --output .usage-rules/.tmp/- + +# Check if usage-rules.md exists +if [ -f ".usage-rules/.tmp/-/usage-rules.md" ]; then + # Create version-specific directory + mkdir -p ".usage-rules/-" + + # Copy main usage rules file + cp ".usage-rules/.tmp/-/usage-rules.md" ".usage-rules/-/" + + # Copy sub-rules if present + if [ -d ".usage-rules/.tmp/-/usage-rules/" ]; then + cp -r ".usage-rules/.tmp/-/usage-rules/" ".usage-rules/-/" + fi + + echo "Usage rules cached in .usage-rules/-/" +else + echo "Package does not provide usage-rules.md" +fi + +# Clean up temp directory +rm -rf ".usage-rules/.tmp/-" +``` + +**Storage location**: `.usage-rules/-/` + +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`: + +```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 + +```bash +# Find all h2 section headings with line numbers +Use Grep: pattern="^## ", path=".usage-rules/-/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 + +```bash +# Extract specific section with content +Use Grep: pattern="^## Querying Data", path=".usage-rules/-/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=150` or read specific ranges + +#### 4.4: Include code examples + +Look for code blocks within sections: + +```bash +# Find code examples in section +Use Grep: pattern="```elixir|# GOOD|# BAD", path=".usage-rules/-/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 : + +**Location**: deps//usage-rules.md +**Version**: + +**Relevant Best Practices** (): + + + +--- + +**Full Rules**: deps//usage-rules.md + +**Integration**: For API documentation, use the hex-docs-search skill. +``` + +### If found in fetched cache: + +``` +Found cached usage rules for : + +**Version**: +**Cache Location**: .usage-rules/-/usage-rules.md + +**Relevant Best Practices** (): + + + +--- + +**Full Rules**: .usage-rules/-/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 '' 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 " 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**: +1. Extract package: `ash` +2. Identify context: "querying" +3. Check `deps/ash/usage-rules.md` (found) +4. Search for section: `## Querying Data` +5. Extract section with code examples +6. 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 + ``` +7. Fetch package: + ```bash + mix hex.package fetch spark 2.2.24 --unpack --output .usage-rules/.tmp/spark-2.2.24 + ``` +8. Extract usage-rules.md (found!) +9. Copy to cache: `.usage-rules/spark-2.2.24/usage-rules.md` +10. Clean up temp +11. 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**: +1. Extract package: `ash` +2. Identify context: "relationship" +3. Check `deps/ash/usage-rules.md` (not found - not in project) +4. Check `.usage-rules/ash-*/usage-rules.md` (found version 3.5.20!) +5. **No fetch needed** - use cached rules +6. Search for "## Relationships" section +7. 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**: +1. Extract package: `ash` +2. Identify context: "actions" + "mistakes" +3. Find usage rules (local or cached) +4. Search for "## Actions" section +5. Also search for keywords: "mistake", "avoid", "wrong", "bad" +6. Extract relevant parts from multiple sections +7. 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: +```elixir +# GOOD - Specific business operations +create :register_user +update :activate_account +update :suspend_for_violation +``` + +**AVOID** - Don't put business logic outside actions: +```elixir +# 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: +```elixir +# 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: + +1. **Glob** - Find usage-rules.md files in deps/, .usage-rules/, and check for sub-rules +2. **Grep** - Search for section headings, context keywords, and code examples +3. **Read** - Read complete usage rules files when broader context needed +4. **Bash** - Fetch packages with mix hex.package, version resolution, extract and cache rules +5. **AskUserQuestion** - Prompt for version when ambiguous + +**Requirements:** curl and jq (Linux/Mac native, use Git Bash or WSL on Windows) + +## Best practices + +1. **Start local**: Always check local dependencies first - they match the version used in the project +2. **Check cache before fetch**: Look for previously fetched rules in `.usage-rules/` before fetching +3. **Context-aware extraction**: Don't present entire file - extract relevant sections based on keywords +4. **Show code examples**: Always include good/bad pattern examples when available +5. **Highlight patterns**: Point out `# GOOD` vs `# BAD` comparisons explicitly +6. **Link to source**: Provide file path so users can explore complete rules +7. **Note integration**: Mention hex-docs-search for complementary API documentation +8. **Git ignore reminder**: Mention .gitignore addition once per session when fetching occurs +9. **Offline capability**: Once fetched, usage rules available without network access +10. **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 `-A` value 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