From pattern-forge
Use after running design to generate the conventions-enforcing agent, CLAUDE.md section, and UserPromptSubmit hook from the selected design patterns.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pattern-forge:generateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Read the design choices and produce three outputs:
Read the design choices and produce three outputs:
.claude/agents/conventions-enforcer.mdCLAUDE.md.claude/settings.json (committable to git for team sharing)The design choices must exist at .claude/pattern-forge/design-choices.json. If they don't exist, tell the user to run /pattern-forge:design first.
Also read .claude/pattern-forge/detection-report.json for ecosystem/framework context.
Create .claude/agents/conventions-enforcer.md (create the .claude/agents/ directory if needed).
---
name: "conventions-enforcer"
description: "[Dynamically generated — see instructions below]"
model: opus
---
Generate the description field dynamically based on the chosen patterns. It must:
- user: "Create a new CRUD form for managing speakers"
assistant: "Let me use the conventions-enforcer agent to ensure the new feature follows all established patterns."
<commentary>Since the user is creating a new feature, use the Agent tool to launch the conventions-enforcer agent.</commentary>
Generate examples relevant to the detected ecosystem and chosen patterns.
Include these sections, all dynamically generated from the design choices:
1. Role Introduction
You are an elite software architect and codebase conventions enforcer
with deep expertise in [framework] and [key libraries from design choices].
Your singular mission is to ensure that every piece of code written in this
project strictly adheres to the established design patterns and conventions.
2. Primary Responsibilities Always include these four:
3. Conventions Sections
For EACH pattern in design-choices.json, generate a numbered convention section with:
Code examples must be realistic — use the actual libraries the user has installed, not pseudocode.
IMPORTANT: Only include ACCEPTED patterns. Do NOT reference rejected suggestions, declined libraries, or skipped categories in the agent. Never write rules like "do not use X" or "X was declined." The agent should only enforce what was chosen. Rejection tracking is handled separately by the update skill via rejections.json — the agent has no role in it.
4. Self-Verification Checklist Generate a checklist with one item per chosen pattern:
- [ ] Using [UI library] components (not custom UI)?
- [ ] Following [pattern name] for [category]?
5. Workflow Always include:
Check if CLAUDE.md exists in the project root.
If CLAUDE.md exists:
<!-- pattern-forge:start --> marker already exists<!-- pattern-forge:start --> and <!-- pattern-forge:end --> with new contentIf CLAUDE.md does not exist:
The section format:
<!-- pattern-forge:start -->
# Codebase Conventions (generated by pattern-forge)
## Stack
- Framework: [framework name and version]
- [One line per key library with its role]
## Key Patterns
- [One line per chosen pattern summarizing the approach]
## Rules
- [Concrete, actionable rules derived from the patterns]
<!-- pattern-forge:end — do not edit between these markers manually -->
Keep it concise — the CLAUDE.md section is passive context, not the full reference.
The hook is a fixed constant. It is not generated, derived, paraphrased, or customized per project. Every project gets the exact same hook entry, byte-for-byte. The hook's only job is to tell Claude to invoke the conventions-enforcer agent — all project-specific rules live in the agent file, never in the hook.
The canonical hook entry (copy verbatim — do not retype, do not reformat, do not substitute printf/echo/python, do not inline project names or pattern rules):
{
"type": "command",
"command": "cat <<'HOOK_EOF'\n{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"IMPORTANT: Whether you are writing a plan or writing code, you MUST validate your work by launching the conventions-enforcer agent (from .claude/agents/) to review your plan or the files you created or modified. Do NOT skip this step — this applies to plans AND code changes.\"}}\nHOOK_EOF",
"timeout": 5
}
The command field above is the canonical command string. It MUST appear in the written file exactly as shown — same characters, same \n escapes, same HOOK_EOF delimiter, same additionalContext text. No variation is acceptable.
First, check if .claude/settings.local.json exists and contains a pattern-forge UserPromptSubmit hook (search for "conventions-enforcer" in the file). If found:
.claude/settings.local.jsonCheck if .claude/settings.json exists.
If it exists:
UserPromptSubmit hook already exists (any entry whose command contains "conventions-enforcer"), remove ithooks.UserPromptSubmit[0].hooks, creating UserPromptSubmit[0] if needed, preserving all other hooks and settingsPostToolUse, PreToolUse, or prompt type hooks — use ONLY UserPromptSubmit with command type as showncommand string — copy it byte-for-byte from the block aboveIf it does not exist:
.claude/settings.json with this exact content (the canonical entry wrapped in the outer shape):{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "cat <<'HOOK_EOF'\n{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":\"IMPORTANT: Whether you are writing a plan or writing code, you MUST validate your work by launching the conventions-enforcer agent (from .claude/agents/) to review your plan or the files you created or modified. Do NOT skip this step — this applies to plans AND code changes.\"}}\nHOOK_EOF",
"timeout": 5
}
]
}
]
}
}
Why this design: The UserPromptSubmit hook fires once when the user sends a prompt, injecting context that tells Claude to dispatch the conventions-enforcer agent. The agent file (.claude/agents/conventions-enforcer.md) contains ALL the convention rules. Writing to .claude/settings.json (not .claude/settings.local.json) means the hook is committed to git — the whole team gets automatic convention enforcement. Keeping the hook a fixed constant (rather than generating it) means every project gets the same tested behavior, and there is no surface area for the generator to leak project-specific content into the hook.
After generating all outputs, update .claude/pattern-forge/history.json:
runs array{
"type": "init",
"timestamp": "ISO 8601 timestamp",
"dependency_snapshot": ["sorted", "dep", "list"],
"patterns_accepted": ["pattern-id-1", "pattern-id-2"],
"patterns_rejected": [],
"libraries_suggested": ["lib1"],
"libraries_accepted": ["lib1"]
}
Before writing any files to disk, validate all three outputs. If ANY check fails, do NOT write files — report the failure and tell the user to re-run /pattern-forge:generate.
Check 1: Agent YAML frontmatter — Verify the generated agent content starts with ---, contains name: and description: fields, and ends with --- before the body.
Check 2: Agent body not empty — Verify at least one ### heading exists under a ## Conventions section, with content (not just whitespace) beneath it.
Check 3: Self-verification checklist not empty — Verify at least one - [ ] checklist item exists in the agent.
Check 4: Hook JSON syntax — Verify the .claude/settings.json content is valid JSON after merging.
Check 5: CLAUDE.md markers present — Verify both <!-- pattern-forge:start --> and <!-- pattern-forge:end --> markers exist in the CLAUDE.md output.
Check 6: No rejected patterns leaked — Scan the generated agent body for these phrases:
To distinguish legitimate rules from leaked rejections: legitimate rules tell you what TO use instead (e.g., "do not use raw fetch — use the centralized API client"), while leaked rejections only say what NOT to use without offering an alternative in the same sentence. Only flag the latter.
Check 7: Hook command string is byte-for-byte identical to the canonical template — Extract the pattern-forge UserPromptSubmit hook entry from the merged .claude/settings.json (the entry whose command contains "conventions-enforcer"). Its command field MUST equal EXACTLY this string, with no differences (not even whitespace, escaping, or trailing content):
cat <<'HOOK_EOF'
{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"IMPORTANT: Whether you are writing a plan or writing code, you MUST validate your work by launching the conventions-enforcer agent (from .claude/agents/) to review your plan or the files you created or modified. Do NOT skip this step — this applies to plans AND code changes."}}
HOOK_EOF
(In the JSON file this is stored as a single-line string with \n escapes and \" escapes, matching the JSON block shown in "Output C: Hook Config".)
Perform an exact string comparison. Any deviation — using printf/echo/python instead of cat, renaming the heredoc delimiter, changing the additionalContext text, adding project name, adding rule summaries, reformatting — fails this check.
If this check fails: the generator produced a non-canonical command. Do NOT attempt to patch the differences. Discard the generated hook entirely and re-emit the canonical hook verbatim from "Output C: Hook Config".
Check 8: Hook has required timeout field — Verify the pattern-forge UserPromptSubmit hook entry includes "timeout": 5. If missing, add it before writing.
If all 8 checks pass: Write the files and add to the confirmation: "Validation: all 8 checks passed."
If any check fails: Report exactly what failed. Do NOT write any files. Tell the user: "Validation failed. The files were not written. Please re-run /pattern-forge:generate to try again."
After generating all three outputs and before presenting the confirmation, check if the project has existing source files. Look for files with these extensions in the project root and subdirectories (excluding node_modules, .git, dist, build, .next, vendor, target, .venv, __pycache__):
.ts, .tsx, .js, .jsx, .py, .rb, .go, .rs, .php, .java, .kt, .swift, .dart
If ANY such files exist, include this line in the confirmation output:
Existing code detected. To align it with your new conventions,
run /pattern-forge:migrate to generate a refactor plan for any pattern.
If no source files exist (fresh project), skip this line.
Tell the user:
/pattern-forge:update any time you add or remove dependencies."Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub samuelasselin/pattern-forge --plugin pattern-forge