From rules-review
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.
npx claudepluginhub hiroro-work/claude-plugins --plugin apply-rulesThis skill is limited to using the following tools:
Merges `.claude/rules/` from multiple projects into a unified portable rule set (.md + .examples.md). Promotes `.local.md` patterns that appear across a threshold of projects by converting them to Principles format. Merges `.examples.md` files alongside rule files.
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.
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.
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'.
Share bugs, ideas, or general feedback.
Merges .claude/rules/ from multiple projects into a unified portable rule set (.md + .examples.md). Promotes .local.md patterns that appear across a threshold of projects by converting them to Principles format. Merges .examples.md files alongside rule files.
/merge-rules # Merge using config file
/merge-rules --config <path> # Merge using specified config file
/merge-rules --dry-run # Show what would be merged without writing
Config file search order:
--config <path> argument.claude/merge-rules.local.md (project-level)~/.claude/merge-rules.local.md (user-level)File format: YAML frontmatter only (no markdown body), same convention as extract-rules.local.md.
---
# Source projects (each must have extract-rules output)
projects:
- ~/projects/frontend-app
- ~/projects/backend-api
- ~/projects/shared-lib
# Output directory (default: .claude/rules/)
output_dir: .claude/rules/
# Rules directory within each project (default: .claude/rules/)
# Corresponds to extract-rules' output_dir setting
rules_dir: .claude/rules/
# Threshold for promoting .local.md patterns (default: 0.5 = majority)
# Examples: 3 projects → 2/3 needed, 4 projects → 3/4, 5 projects → 3/5
promote_threshold: 0.5
# Report language (default: ja)
language: ja
---
.claude/merge-rules.local.md or specify with --config."language resolution order: Skill config → Claude Code settings (~/.claude/settings.json → language field) → default japrojects must have at least 2 entriesrules_dirFor each project:
.md, .local.md, and .examples.md files under {path}/{rules_dir}/ (recursive)languages/*.md → portable principles (always merge). If the file also contains ## Project-specific patterns (hybrid format from split_output: false), treat patterns as promotion candidates (same as .local.md)frameworks/*.md → same as aboveintegrations/*.md → same as abovelanguages/*.local.md → promotion candidateframeworks/*.local.md → promotion candidateintegrations/*.local.md → promotion candidatelanguages/*.examples.md → example file (merge with rules)frameworks/*.examples.md → example file (merge with rules)integrations/*.examples.md → example file (merge with rules)project.md → skip (inherently project-specific)project.examples.md → skip (inherently project-specific)paths:) and body sections (## Principles, ## Project-specific patterns, ## Principles Examples, ## Project-specific Examples)Before merging, group files that refer to the same concept but have different names. This applies to .md, .local.md, and .examples.md files — a .md and its corresponding .local.md and .examples.md share the same normalization (e.g., rails-controller.md, rails-controller.local.md, and rails-controller.examples.md are normalized together with their rails-controllers.* variants).
rails-controller.md vs rails-controllers.md, rails-model.md vs rails-models.md)
controller / controllers)paths: frontmatter overlap)<framework>-<layer>)rails-controller.md + rails-controllers.md → rails-controllers.md")Design note: Once a pattern is promoted to a Principle (via Step 5), it becomes a permanent org-level rule. Subsequent merge-rules runs will preserve it through Step 4's principle deduplication, regardless of whether the original .local.md pattern still meets the promotion threshold. To demote or remove a promoted Principle, manually edit the org rules output.
For each unique (normalized) file name across projects (e.g., languages/typescript.md, integrations/rails-inertia.md):
## Principles sections:
paths: frontmatter: union of all path patterns, deduplicateFor each normalized category (e.g., languages/typescript, frameworks/rails-controllers, integrations/rails-inertia):
## Project-specific patterns from all projects — from .local.md files and from hybrid .md files that contain this section (see Step 2)-) semantically matches an existing principle name in the corresponding .md output (from Step 4). Use AI judgment for semantic equivalence (case-insensitive, synonyms). This prevents self-amplification when .local.md contains patterns previously promoted by older versions-)
useAuth() and useAuth() → { user, login, logout } refer to the same pattern)len(projects) * promote_threshold projects (i.e., strict majority when threshold = 0.5)## Principles in the corresponding normalized .md output:
`signature` - description → Principles format: Description (simplified signature)`useAuth() → { user, login, logout }` - auth hook interface → Auth hook interface (useAuth)`clean_bracket_params(:keyword)` - WAF付加のブラケット除去 → WAF付加のブラケット除去 (clean_bracket_params)`RefOrNull<T extends { id: string }> = T | { id: null }` - nullable refs → Nullable refs (RefOrNull<T>)For each normalized .examples.md file group:
### FP only)
## Principles Examples
### example headings to promoted patterns — do not rely solely on exact heading match### title uses the converted Principle name (from Step 5), not the original signature.examples.md file structure:# <Category> Rules - Examples
## Principles Examples
### <Principle name>
**Good:**
```<lang>
<example>
Bad:
<example>
- `###` titles must match the corresponding rule name in the merged output `.md` file. Do not rephrase
- No `paths:` frontmatter (prevents auto-loading)
- If no examples exist for any merged rule, skip generating the `.examples.md` file
### Step 6: Write Output
1. Check output directory:
- If `--dry-run`: skip writing, show planned file list with contents summary, then go to Step 7
- If exists and has files: warn and ask for confirmation before overwriting
- If not exists: create with `mkdir -p`
2. Write merged files preserving directory structure:
- `languages/<lang>.md`
- `languages/<lang>.examples.md` (if examples exist)
- `frameworks/<framework>.md`
- `frameworks/<framework>.examples.md` (if examples exist)
- `integrations/<framework>-<integration>.md`
- `integrations/<framework>-<integration>.examples.md` (if examples exist)
- Only `.md` and `.examples.md` files (no `.local.md` in output)
3. Output file format:
```markdown
---
paths:
- "**/*.ts"
- "**/*.tsx"
---
# TypeScript Rules
## Principles
- Immutability (spread, map/filter/reduce, const)
- Type safety (strict mode, explicit annotations, no any)
- Auth hook interface (useAuth)
.md contains only ## Principles (promoted patterns are converted and included here)## Principles section if no principles exist for this category.examples.md was generated, append a reference section at the end:
## Examples
When in doubt: ./<name>.examples.md
Display report using the project's directory name (last path component) as label. Report headers are always in English.
# Merge Rules Report
## Sources
- frontend-app (3 files)
- backend-api (2 files)
- shared-lib (4 files)
## File Name Normalization
- `rails-controller.md` + `rails-controllers.md` → `rails-controllers.md`
- `rails-model.md` + `rails-models.md` → `rails-models.md`
## Merge Results
| File | Sources | Principles | Promoted to Principles | Examples |
|------|---------|------------|------------------------|----------|
| languages/typescript.md | 3/3 | 5 | 2 | 7 |
| frameworks/react.md | 2/3 | 3 | 1 | 4 |
| integrations/rails-inertia.md | 2/3 | 2 | 0 | 2 |
**Principles** = total including promoted. **Examples** = total `###` entries in the output `.examples.md`.
## Promoted to Principles
- `useAuth()` → Auth hook interface (useAuth) - 3/3 projects
- `pathFor() + url()` → Path helpers (pathFor, url) - 2/3 projects
## Below Threshold (reference)
- `useCustomHook()` (typescript) - 1/3 (frontend-app only)
- `ApiClient.create()` (typescript) - 1/3 (backend-api only)
## Skipped
- project.md x3 (project-specific, skipped)