From rules-review
Applies organization-wide rules from merge-rules output to current project. Detects tech stack, merges Principles, cleans .local.md patterns, and fixes non-conforming files.
npx claudepluginhub hiroro-work/claude-plugins --plugin rules-reviewThis skill is limited to using the following tools:
Applies organization-wide rules (produced by merge-rules) to the current project. Detects the project's tech stack, selects relevant rules, merges them with existing extract-rules output, cleans up promoted patterns from `.local.md` files, and ensures the final structure conforms to the extract-rules/merge-rules convention.
Merges .claude/rules/ from multiple projects into unified portable rules and examples. Promotes shared .local.md patterns across projects to Principles format using configurable threshold.
Guides creation of .claude/rules/ files for path-scoped project conventions using TDD workflow: RED (test gaps), GREEN (write rule), REFACTOR (optimize). Triggers on 'add rule', 'create convention', 'scope guideline'.
Manages modular Claude rules in .claude/rules/ directory, supporting path-specific globs, brace expansion, project-wide, and user-level rules. Use to create, edit, list, generate, or sync rules.
Share bugs, ideas, or general feedback.
Applies organization-wide rules (produced by merge-rules) to the current project. Detects the project's tech stack, selects relevant rules, merges them with existing extract-rules output, cleans up promoted patterns from .local.md files, and ensures the final structure conforms to the extract-rules/merge-rules convention.
/apply-rules <source> # Apply from GitHub URL or local path
/apply-rules # Apply using config file
/apply-rules --config <path> # Apply using specified config file
/apply-rules --dry-run # Show what would change without writing
/apply-rules --dry-run <source> # Dry run with specified source
<source> points directly to the rules directory (merge-rules or extract-rules output):
https://github.com/org/repo/tree/main/.claude/rules~/org-rules/.claude/rulesConfig file search order:
--config <path> argument.claude/apply-rules.local.md (project-level)~/.claude/apply-rules.local.md (user-level)File format: YAML frontmatter only (no markdown body), same convention as extract-rules.local.md and merge-rules.local.md.
---
# Rules directory (GitHub URL or local path)
# GitHub: https://github.com/org/repo/tree/main/.claude/rules
# Local: ~/org-rules/.claude/rules
source: https://github.com/org/repo/tree/main/.claude/rules
# Alternative: specify GitHub source components separately
# (useful when branch name contains "/" or for tags/SHAs)
# source_repo: org/repo
# source_ref: feature/rules-v2
# source_path: .claude/rules
# Output directory in target project (default: .claude/rules/)
output_dir: .claude/rules/
# Auto-detect which rules to apply (default: true)
# When false, applies ALL rules from source
auto_detect: true
# Explicitly include rules even if not auto-detected
include: []
# Example: [languages/typescript, integrations/rails-inertia]
# Explicitly exclude rules even if auto-detected
exclude: []
# Example: [frameworks/rails-views]
# Report language (default: ja)
language: ja
---
CLI argument <source> overrides the config's source field.
<source> argument provided, use it (overrides config source)language resolution order: Skill config → Claude Code settings (~/.claude/settings.json → language field) → default jasource must be specified (via CLI argument or config file).claude/apply-rules.local.md with a source: field."If source is a local path:
~ and resolve to absolute path.md)If source is a GitHub URL:
Parse URL to extract owner, repo, branch, and path:
https://github.com/{owner}/{repo}/tree/{branch}/{path}https://github.com/org/repo/tree/main/.claude/rules
→ owner: org, repo: repo, branch: main, path: .claude/rulesNote on ambiguous refs: Branch names may contain / (e.g., feature/rules-v2), and refs can also be tags or SHAs. Simple URL splitting cannot reliably separate ref from path. To handle this robustly:
gh api repos/{owner}/{repo}/git/ref/{candidate}source_repo: org/repo
source_ref: feature/rules-v2
source_path: .claude/rules
When these fields are present, they take precedence over URL parsing.main or master), simple URL parsing works.Fetch using gh api:
gh auth statusmktemp -dgh api repos/{owner}/{repo}/contents/{path}?ref={branch}
For each entry with type: "dir", recursively fetch subdirectory contents:
gh api repos/{owner}/{repo}/contents/{path}/{subdir}?ref={branch}
This dynamically discovers all categories (not limited to languages/, frameworks/, integrations/)..md file found, fetch content and decode:
gh api repos/{owner}/{repo}/contents/{file_path}?ref={branch} --jq '.content | @base64d'
Save to tmpdir preserving directory structureInventory source files:
**/*.md and **/*.examples.md under the source rules directoryproject.md and project.examples.md (inherently project-specific).local.md files (merge-rules output should not contain these, but handle gracefully)paths:) and body sectionsAnalyze the current working directory to determine which source rules are relevant. Detection is best-effort, based on dependency files (e.g., Gemfile, package.json) and project directory structure (e.g., app/controllers/).
Read references/detection-heuristics.md for the full detection table mapping indicators to rule files. If the source contains rule files not covered in the table, use AI judgment to match them against the project's dependencies and file structure.
Apply overrides:
include: entries to the detected setexclude: entries from the detected setauto_detect: false: start with ALL source rules, then apply exclude onlyIf auto_detect: false: Apply ALL source rules (minus exclude entries). Skip the proposal step entirely — no integration proposals or skipped rules. Proceed directly to Step 5.
If auto_detect: true (default):
Auto-matched rules: Rules that match detected tech stack → apply automatically
Integration proposals: For integrations NOT detected in the project but related to a detected framework (e.g., source has integrations/rails-pundit but project doesn't use pundit), use AskUserQuestion to present them as a single list:
The following integration rules are available in the source but were not detected in your project. Which would you like to apply?
integrations/rails-pundit— Authorization library Pundit rulesintegrations/rails-good-job— Job queue GoodJob rulesOptions: all / none / specify by number (e.g. "1" or "1,2")
Apply only those the user approves.
Skipped rules: Rules for tech not detected and not in related frameworks → skip, list in report
{output_dir}/ exists in the target project.md, .local.md, .examples.md.md file contains ## Project-specific patterns (hybrid format from extract-rules split_output: false), note this. The merge step will convert hybrid to split format because the split format (separate .md and .local.md) is the standard expected by both extract-rules and merge-rules, and mixing formats causes confusion when rules flow back through the pipeline. Note: source files from merge-rules should not contain ## Project-specific patterns (promoted patterns are converted to Principles format)Before merging, align target file names with source (canonical) names. This prevents duplicate files for the same concept (e.g., rails-controller.md vs rails-controllers.md).
controller/controllers), minor differences for the same conceptAskUserQuestion to confirm:
The following target files will be renamed to match source (canonical) names:
frameworks/rails-controller.md→frameworks/rails-controllers.mdOptions: all / none / specify by number
For each filtered source rule file, determine the merge action:
6a. Merge .md files (Principles):
Case: No existing .md
.md as-is (source from merge-rules contains only ## Principles)Case: Existing .md exists
paths: frontmatter: Union of all path patterns, deduplicate.md contains ## Project-specific patterns (hybrid format):
.local.md (create if not exists, append if exists).md, keeping only ## Principles## Principles:
AskUserQuestion to present them together:
The following principles differ between org rules and project rules:
1. Immutability (in
languages/ruby.md)
- Org:
Immutability (spread, map/filter/reduce, const)- Project:
Immutability (freeze, deep clone, readonly)2. Error handling (in
frameworks/rails.md)
- Org:
Error handling (rescue, custom exceptions)- Project:
Error handling (rescue, retry, circuit breaker)For each, choose: (a) Adopt org rule / (b) Keep project rule / (c) Keep both Example: "1a, 2c" or "all a"
6b. Clean up promoted patterns from .local.md files:
.local.md files contain project-specific patterns discovered by extract-rules. When org rules promote a pattern to a Principle, the original pattern in .local.md becomes redundant. apply-rules cleans up these duplicates while preserving genuinely project-specific patterns.
.local.md.local.md for patterns whose description matches a Principle name now present in the corresponding .md (e.g., `useAuth() → { user, login, logout }` - auth hook interface is a duplicate of Auth hook interface (useAuth) in ## Principles). Use AI judgment for semantic equivalence (case-insensitive, synonyms).local.md.local.md becomes empty after removal, delete the file6c. Merge .examples.md files:
Case: No existing .examples.md
.examples.md as-is (source from merge-rules contains only ## Principles Examples)Case: Existing .examples.md exists
## Principles Examples: Add examples from source for principles not already covered in target## Project-specific Examples (target only): Remove examples whose ### title corresponds to patterns removed from .local.md in Step 6b. Preserve all other existing entries6d. Ensure ## Examples reference:
.md and .local.md that still exists and has a corresponding .examples.md must end with:
## Examples
When in doubt: ./<name>.examples.md
.local.md was deleted in Step 6b (became empty), no reference is neededScan output_dir for files that don't conform to extract-rules/merge-rules convention:
Valid patterns:
{category}/{name}.md{category}/{name}.local.md{category}/{name}.examples.mdproject.mdproject.examples.mdValid categories: languages/, frameworks/, integrations/
Non-conforming file handling:
paths: hints)AskUserQuestion to present the migration plan as a single list for confirmation:
The following non-conforming files were detected. Migrate their rules to conforming files and delete them?
frameworks/old-custom-rules.md→ migrate toframeworks/rails.mdruby-rules.md→ migrate tolanguages/ruby.mdproject.rules.md→ migrate toproject.md(project file — confirm individually)Options: all / none / specify by number (e.g. "1,2")
Note:
project.*files are excluded from "all". Specify them individually by number.
If source was a GitHub URL, remove the temp directory: rm -rf <tmpdir>
Display report. Report headers are always in English, content in the configured language.
# Apply Rules Report
## Source
- https://github.com/org/repo/tree/main/.claude/rules (15 rule files)
## Target Project Detection
- Languages: ruby
- Frameworks: rails, rails-controllers, rails-models, rails-views
- Integrations: rails-devise, rails-pundit
## Applied Rules
| File | Action | Principles |
|------|--------|------------|
| languages/ruby.md | Merged | +3 added, 7 kept |
| frameworks/rails.md | Created | 13 |
| frameworks/rails-controllers.md | Created | 5 |
| integrations/rails-devise.md | Merged | +1 added |
## Promoted Pattern Cleanup
- languages/ruby.local.md: removed 1 pattern (now in Principles)
- frameworks/rails.local.md: no duplicates found
## Preserved
- languages/ruby.local.md (2 remaining patterns)
- frameworks/rails.local.md (3 patterns, untouched)
## User-approved Integrations
- integrations/rails-pundit (not detected, approved by user)
## Skipped (not relevant to project)
- languages/typescript.md
- frameworks/react.md
- frameworks/nextjs.md
- integrations/rails-stripe.md
## Structure Cleanup
- frameworks/old-custom.md → rules migrated to frameworks/rails.md → deleted
## Conflicts (resolved by user)
- languages/ruby.md: "Immutability" → user chose: Keep both
Summary of user-confirmation points and automatic actions:
| Situation | Action |
|---|---|
| Principle in source, not in target | Auto-add |
| Principle in target, not in source | Auto-keep |
| Same principle, different hints | Auto-union hints |
| Same principle name, different content | AskUserQuestion: collect all conflicts, present together (adopt org / keep project / keep both) |
| Non-conforming file detected | AskUserQuestion: present migration plan as single list for confirmation |
project.* non-conforming file | Excluded from "all" — must be specified individually by number |
| Target file name differs from source canonical name | AskUserQuestion: confirm renames (all / none / specify) |
| Undetected integration rule (related framework) | AskUserQuestion: present as single list for approval (all / none / specify) |
.local.md pattern matching a Principle | Auto-remove from .local.md (cross-format duplicate cleanup) |
.local.md pattern not matching any Principle | Preserved |
## Project-specific Examples for removed pattern | Auto-remove |
## Project-specific Examples for remaining pattern | Preserved |