mirror of
https://github.com/alirezarezvani/ClaudeForge.git
synced 2026-07-03 02:13:15 -04:00
a45e6f5dbd
Turns ClaudeForge into an installable Claude Code plugin and adds the missing pieces for a clean lifecycle: hard line-cap enforcement, modular chaining via @path imports, a sync/cleanup command, and Explore-agent delegation for project discovery. - .claude-plugin/plugin.json: plugin manifest registering both skills, both commands, and the guardian agent (installable via /plugin marketplace add alirezarezvani/ClaudeForge && /plugin install claudeforge) - skill/validator.py: MAX_RECOMMENDED_LINES 300 -> 150 (warning at 120) - skill/template_selector.py: target_lines capped at 150 across all team sizes (solo 75 / small 100 / medium 125 / large 150) so any single CLAUDE.md fits within the cap; bigger projects spread content across modular sub-files - skill/analyzer.py: length thresholds, quality scoring, and recommendations rebased on the 150 cap (was 300/400) - skill/generator.py: modular root now emits @path imports next to the human-readable links; every sub-CLAUDE.md gets a back-link header pointing to ../CLAUDE.md (markdown + @import) for bidirectional chaining - command/sync-claude-md.md: new /sync-claude-md command that inventories every CLAUDE.md, prunes stale references, enforces the 150 cap by splitting into sub-files, and repairs the root <-> sub chain - command/enhance-claude-md.md: discovery phase now delegates the deep codebase scan to the Explore subagent to keep context lean - install.sh / install.ps1: each command in command/ installs as its own ~/.claude/commands/<name>.md (legacy bundle backed up on upgrade) - skill/SKILL.md, CLAUDE.md, README.md, CHANGELOG.md: docs updated for the plugin install path, sync command, and new line cap Verified via smoke test: validator constants, template targets, generator output line counts across 5 presets (all <= 150), context files with backlinks, @-import chain in modular root, idempotent merge_with_existing, validator status transitions at the new cap, analyzer quality differential, and plugin manifest JSON shape with all referenced paths existing on disk.
505 lines
19 KiB
Python
505 lines
19 KiB
Python
"""
|
|
CLAUDE.md Template Selector
|
|
|
|
Selects appropriate CLAUDE.md templates based on project context.
|
|
Provides intelligent template selection, customization, and recommendations.
|
|
"""
|
|
|
|
from typing import Dict, List, Any, Optional
|
|
|
|
|
|
class TemplateSelector:
|
|
"""Selects and customizes CLAUDE.md templates based on project context."""
|
|
|
|
# Template definitions by project type
|
|
PROJECT_TEMPLATES = {
|
|
"web_app": {
|
|
"focus": "Frontend components, UI/UX, state management",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Component Standards",
|
|
"State Management", "Styling Guidelines", "Testing Requirements",
|
|
"Performance Optimization", "Accessibility"
|
|
],
|
|
"tech_hints": ["react", "vue", "angular", "svelte"]
|
|
},
|
|
"api": {
|
|
"focus": "Backend services, REST/GraphQL, database operations",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "API Design",
|
|
"Database Guidelines", "Error Handling", "Testing Requirements",
|
|
"Security Practices", "Documentation Standards"
|
|
],
|
|
"tech_hints": ["node", "python", "go", "java", "fastapi", "express"]
|
|
},
|
|
"fullstack": {
|
|
"focus": "Integrated frontend + backend, end-to-end workflows",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Frontend Guidelines",
|
|
"Backend Guidelines", "Database Operations", "API Integration",
|
|
"Testing Strategy", "Deployment Process"
|
|
],
|
|
"tech_hints": ["next.js", "django", "rails", "laravel"]
|
|
},
|
|
"cli": {
|
|
"focus": "Command-line interface, user interaction, scripting",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Command Structure",
|
|
"Argument Parsing", "Error Handling", "Testing Requirements",
|
|
"Documentation Standards", "Distribution"
|
|
],
|
|
"tech_hints": ["click", "commander", "cobra", "clap"]
|
|
},
|
|
"library": {
|
|
"focus": "Reusable package, API design, versioning",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Public API Design",
|
|
"Versioning Strategy", "Testing Requirements", "Documentation Standards",
|
|
"Breaking Changes", "Release Process"
|
|
],
|
|
"tech_hints": ["npm", "pypi", "crates.io", "maven"]
|
|
},
|
|
"mobile": {
|
|
"focus": "Mobile UI, platform-specific code, performance",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Platform Guidelines",
|
|
"Navigation Patterns", "State Management", "Performance Optimization",
|
|
"Testing Requirements", "Release Process"
|
|
],
|
|
"tech_hints": ["react-native", "flutter", "ios", "android"]
|
|
},
|
|
"desktop": {
|
|
"focus": "Desktop application, native integration, distribution",
|
|
"sections": [
|
|
"Quick Navigation", "Core Principles", "Window Management",
|
|
"Native Integration", "State Management", "Testing Requirements",
|
|
"Build Process", "Distribution"
|
|
],
|
|
"tech_hints": ["electron", "tauri", "qt", "gtk"]
|
|
}
|
|
}
|
|
|
|
# Team size templates. All targets stay <= MAX_LINES_PER_FILE (150) so any
|
|
# single CLAUDE.md remains within the hard cap; larger projects spread
|
|
# content across modular sub-files instead of growing the root file.
|
|
MAX_LINES_PER_FILE = 150
|
|
|
|
TEAM_SIZE_TEMPLATES = {
|
|
"solo": {
|
|
"target_lines": 75,
|
|
"complexity": "minimal",
|
|
"focus": "Efficiency, personal workflow",
|
|
"detail_level": "concise"
|
|
},
|
|
"small": {
|
|
"target_lines": 100,
|
|
"complexity": "core",
|
|
"focus": "Core guidelines, collaboration basics",
|
|
"detail_level": "moderate"
|
|
},
|
|
"medium": {
|
|
"target_lines": 125,
|
|
"complexity": "detailed",
|
|
"focus": "Team coordination, process standardization",
|
|
"detail_level": "comprehensive"
|
|
},
|
|
"large": {
|
|
"target_lines": 150,
|
|
"complexity": "comprehensive",
|
|
"focus": "Enterprise standards, governance",
|
|
"detail_level": "extensive"
|
|
}
|
|
}
|
|
|
|
# Development phase templates
|
|
PHASE_TEMPLATES = {
|
|
"prototype": {
|
|
"priority": ["Quick start", "Flexibility", "Rapid iteration"],
|
|
"skip_sections": ["Security Practices", "Performance Optimization"]
|
|
},
|
|
"mvp": {
|
|
"priority": ["Core features", "Testing basics", "Documentation"],
|
|
"skip_sections": []
|
|
},
|
|
"production": {
|
|
"priority": ["Quality", "Security", "Performance", "Monitoring"],
|
|
"skip_sections": []
|
|
},
|
|
"enterprise": {
|
|
"priority": ["Compliance", "Security", "Scalability", "Governance"],
|
|
"skip_sections": []
|
|
}
|
|
}
|
|
|
|
def __init__(self, project_context: Dict[str, Any]):
|
|
"""
|
|
Initialize template selector with project context.
|
|
|
|
Args:
|
|
project_context: Dictionary containing project type, tech_stack, team_size, etc.
|
|
"""
|
|
self.project_type = project_context.get('type', 'web_app')
|
|
self.tech_stack = project_context.get('tech_stack', [])
|
|
self.team_size = project_context.get('team_size', 'small')
|
|
self.phase = project_context.get('phase', 'mvp')
|
|
self.workflows = project_context.get('workflows', [])
|
|
self.modular = project_context.get('modular', False)
|
|
|
|
def select_template(self) -> Dict[str, Any]:
|
|
"""
|
|
Select the most appropriate template based on project context.
|
|
|
|
Returns:
|
|
Template configuration dictionary
|
|
"""
|
|
# Get base template for project type
|
|
project_template = self.PROJECT_TEMPLATES.get(
|
|
self.project_type,
|
|
self.PROJECT_TEMPLATES['web_app']
|
|
)
|
|
|
|
# Get team size configuration
|
|
team_config = self.TEAM_SIZE_TEMPLATES.get(
|
|
self.team_size,
|
|
self.TEAM_SIZE_TEMPLATES['small']
|
|
)
|
|
|
|
# Get phase configuration
|
|
phase_config = self.PHASE_TEMPLATES.get(
|
|
self.phase,
|
|
self.PHASE_TEMPLATES['mvp']
|
|
)
|
|
|
|
# Combine into final template
|
|
return {
|
|
"project_type": self.project_type,
|
|
"team_size": self.team_size,
|
|
"phase": self.phase,
|
|
"target_lines": team_config['target_lines'],
|
|
"complexity": team_config['complexity'],
|
|
"sections": self._select_sections(
|
|
project_template['sections'],
|
|
phase_config
|
|
),
|
|
"focus": project_template['focus'],
|
|
"detail_level": team_config['detail_level'],
|
|
"tech_customization": self._get_tech_customization(),
|
|
"modular_recommended": self.recommend_modular_structure()
|
|
}
|
|
|
|
def _select_sections(self, base_sections: List[str], phase_config: Dict[str, Any]) -> List[str]:
|
|
"""
|
|
Select sections based on phase and priorities.
|
|
|
|
Args:
|
|
base_sections: List of base section names
|
|
phase_config: Phase configuration dictionary
|
|
|
|
Returns:
|
|
Filtered list of sections
|
|
"""
|
|
skip_sections = phase_config.get('skip_sections', [])
|
|
return [section for section in base_sections if section not in skip_sections]
|
|
|
|
def _get_tech_customization(self) -> Dict[str, Any]:
|
|
"""
|
|
Get tech stack-specific customizations.
|
|
|
|
Returns:
|
|
Tech customization configuration
|
|
"""
|
|
customizations = {
|
|
"languages": [],
|
|
"frameworks": [],
|
|
"tools": [],
|
|
"specific_guidelines": []
|
|
}
|
|
|
|
# Detect languages
|
|
lang_map = {
|
|
'typescript': 'TypeScript',
|
|
'javascript': 'JavaScript',
|
|
'python': 'Python',
|
|
'go': 'Go',
|
|
'rust': 'Rust',
|
|
'java': 'Java',
|
|
'kotlin': 'Kotlin',
|
|
'ruby': 'Ruby',
|
|
'php': 'PHP'
|
|
}
|
|
|
|
for tech in self.tech_stack:
|
|
tech_lower = tech.lower()
|
|
if tech_lower in lang_map:
|
|
customizations['languages'].append(lang_map[tech_lower])
|
|
|
|
# Detect frameworks
|
|
framework_map = {
|
|
'react': 'React',
|
|
'vue': 'Vue',
|
|
'angular': 'Angular',
|
|
'svelte': 'Svelte',
|
|
'next.js': 'Next.js',
|
|
'django': 'Django',
|
|
'fastapi': 'FastAPI',
|
|
'flask': 'Flask',
|
|
'express': 'Express',
|
|
'gin': 'Gin',
|
|
'echo': 'Echo',
|
|
'spring': 'Spring Boot',
|
|
'rails': 'Rails'
|
|
}
|
|
|
|
for tech in self.tech_stack:
|
|
tech_lower = tech.lower()
|
|
if tech_lower in framework_map:
|
|
customizations['frameworks'].append(framework_map[tech_lower])
|
|
|
|
# Detect tools
|
|
tool_map = {
|
|
'docker': 'Docker',
|
|
'kubernetes': 'Kubernetes',
|
|
'postgresql': 'PostgreSQL',
|
|
'mongodb': 'MongoDB',
|
|
'redis': 'Redis',
|
|
'git': 'Git',
|
|
'github': 'GitHub',
|
|
'gitlab': 'GitLab'
|
|
}
|
|
|
|
for tech in self.tech_stack:
|
|
tech_lower = tech.lower()
|
|
if tech_lower in tool_map:
|
|
customizations['tools'].append(tool_map[tech_lower])
|
|
|
|
# Add specific guidelines based on tech stack
|
|
if 'typescript' in [t.lower() for t in self.tech_stack]:
|
|
customizations['specific_guidelines'].append(
|
|
"Use TypeScript strict mode throughout the project"
|
|
)
|
|
|
|
if 'react' in [t.lower() for t in self.tech_stack]:
|
|
customizations['specific_guidelines'].append(
|
|
"Prefer functional components with hooks over class components"
|
|
)
|
|
|
|
if 'python' in [t.lower() for t in self.tech_stack]:
|
|
customizations['specific_guidelines'].append(
|
|
"Use type hints for all function signatures (Python 3.10+)"
|
|
)
|
|
|
|
if 'docker' in [t.lower() for t in self.tech_stack]:
|
|
customizations['specific_guidelines'].append(
|
|
"Use multi-stage Dockerfiles for optimized image size"
|
|
)
|
|
|
|
return customizations
|
|
|
|
def recommend_modular_structure(self) -> bool:
|
|
"""
|
|
Determine if modular CLAUDE.md structure is recommended.
|
|
|
|
Returns:
|
|
True if modular structure recommended, False otherwise
|
|
"""
|
|
# Recommend modular structure for:
|
|
# 1. Full-stack projects
|
|
# 2. Large teams
|
|
# 3. Production/enterprise phase
|
|
# 4. Projects with 3+ major tech stack components
|
|
|
|
if self.project_type == 'fullstack':
|
|
return True
|
|
|
|
if self.team_size in ['medium', 'large']:
|
|
return True
|
|
|
|
if self.phase in ['production', 'enterprise']:
|
|
return True
|
|
|
|
if len(self.tech_stack) >= 3:
|
|
return True
|
|
|
|
# User explicitly requested modular
|
|
if self.modular:
|
|
return True
|
|
|
|
return False
|
|
|
|
def customize_template(self, template: Dict[str, Any]) -> str:
|
|
"""
|
|
Generate customized CLAUDE.md content based on template.
|
|
|
|
Args:
|
|
template: Template configuration dictionary
|
|
|
|
Returns:
|
|
Customized CLAUDE.md content as string
|
|
"""
|
|
lines = []
|
|
|
|
# Add title
|
|
lines.append("# CLAUDE.md")
|
|
lines.append("")
|
|
lines.append(f"This file provides guidance for Claude Code when working with this {self.project_type} project.")
|
|
lines.append("")
|
|
|
|
# Add modular navigation if recommended
|
|
if template.get('modular_recommended'):
|
|
lines.append("## Quick Navigation")
|
|
lines.append("")
|
|
lines.extend(self._generate_navigation_links())
|
|
lines.append("")
|
|
|
|
# Add core principles
|
|
lines.append("## Core Principles")
|
|
lines.append("")
|
|
lines.extend(self._generate_core_principles(template))
|
|
lines.append("")
|
|
|
|
# Add behavioral guidelines (Karpathy principles) - applied to every project
|
|
lines.append("## Behavioral Guidelines")
|
|
lines.append("")
|
|
lines.extend(self._generate_karpathy_guidelines())
|
|
lines.append("")
|
|
|
|
# Add tech stack section
|
|
if self.tech_stack:
|
|
lines.append("## Tech Stack")
|
|
lines.append("")
|
|
lines.extend(self._generate_tech_stack_section(template))
|
|
lines.append("")
|
|
|
|
# Add workflow section if workflows specified
|
|
if self.workflows:
|
|
lines.append("## Workflow Instructions")
|
|
lines.append("")
|
|
lines.extend(self._generate_workflow_section())
|
|
lines.append("")
|
|
|
|
# Add additional sections based on template
|
|
for section in template['sections']:
|
|
if section not in ["Quick Navigation", "Core Principles", "Tech Stack", "Workflow Instructions"]:
|
|
lines.append(f"## {section}")
|
|
lines.append("")
|
|
lines.append(f"[Add {section.lower()} guidelines specific to your project]")
|
|
lines.append("")
|
|
|
|
return '\n'.join(lines)
|
|
|
|
def _generate_navigation_links(self) -> List[str]:
|
|
"""Generate navigation links for modular structure."""
|
|
links = []
|
|
|
|
if self.project_type == 'fullstack':
|
|
links.append("- [Backend Guidelines](backend/CLAUDE.md)")
|
|
links.append("- [Frontend Guidelines](frontend/CLAUDE.md)")
|
|
links.append("- [Database Operations](database/CLAUDE.md)")
|
|
|
|
if 'cicd' in self.workflows:
|
|
links.append("- [CI/CD Workflows](.github/CLAUDE.md)")
|
|
|
|
if not links:
|
|
links.append("- [Context-specific guides will be linked here]")
|
|
|
|
return links
|
|
|
|
def _generate_core_principles(self, template: Dict[str, Any]) -> List[str]:
|
|
"""Generate core principles based on template."""
|
|
principles = []
|
|
|
|
# Add workflow-specific principles
|
|
if 'tdd' in self.workflows:
|
|
principles.append("1. **Test-Driven Development**: Write tests before implementation")
|
|
|
|
# Add tech-specific principles
|
|
tech_custom = template.get('tech_customization', {})
|
|
for i, guideline in enumerate(tech_custom.get('specific_guidelines', [])[:3], start=len(principles)+1):
|
|
principles.append(f"{i}. **{guideline.split(':')[0] if ':' in guideline else 'Guideline'}**: {guideline}")
|
|
|
|
# Add generic principles if needed
|
|
if len(principles) < 3:
|
|
generic = [
|
|
"**Code Quality**: Maintain high code quality with clear, readable implementations",
|
|
"**Documentation**: Keep documentation in sync with code changes",
|
|
"**Error Handling**: Implement comprehensive error handling from the start"
|
|
]
|
|
for i, principle in enumerate(generic[:3-len(principles)], start=len(principles)+1):
|
|
principles.append(f"{i}. {principle}")
|
|
|
|
return principles
|
|
|
|
def _generate_tech_stack_section(self, template: Dict[str, Any]) -> List[str]:
|
|
"""Generate tech stack section."""
|
|
lines = []
|
|
tech_custom = template.get('tech_customization', {})
|
|
|
|
if tech_custom.get('languages'):
|
|
lines.append(f"- **Languages**: {', '.join(tech_custom['languages'])}")
|
|
|
|
if tech_custom.get('frameworks'):
|
|
lines.append(f"- **Frameworks**: {', '.join(tech_custom['frameworks'])}")
|
|
|
|
if tech_custom.get('tools'):
|
|
lines.append(f"- **Tools**: {', '.join(tech_custom['tools'])}")
|
|
|
|
if not lines:
|
|
lines.append("- [Add your tech stack details here]")
|
|
|
|
return lines
|
|
|
|
def _generate_karpathy_guidelines(self) -> List[str]:
|
|
"""Emit the embedded Karpathy guidelines section.
|
|
|
|
Distilled summary intended for every generated CLAUDE.md. Full skill
|
|
text lives in the ``karpathy-guidelines`` skill installed alongside
|
|
ClaudeForge.
|
|
"""
|
|
return [
|
|
"Behavioral guardrails applied to every coding, review, and refactoring task.",
|
|
"Full skill: `~/.claude/skills/karpathy-guidelines/SKILL.md`.",
|
|
"",
|
|
"1. **Think before coding.** State load-bearing assumptions; if a request "
|
|
"has multiple reasonable interpretations, surface them instead of picking "
|
|
"silently. Stop and ask when something is genuinely unclear.",
|
|
"2. **Simplicity first.** Write the minimum code that solves the stated "
|
|
"problem. No speculative abstractions, no unrequested configuration, no "
|
|
"error handling for conditions that cannot occur. If the first draft is "
|
|
"much larger than necessary, rewrite before shipping.",
|
|
"3. **Surgical changes.** Touch only what the task requires. Do not "
|
|
"opportunistically reformat or refactor adjacent code, and match the "
|
|
"surrounding style. Every changed line should trace directly to the "
|
|
"user's request.",
|
|
"4. **Goal-driven execution.** Convert vague requests into verifiable "
|
|
"success criteria before coding (e.g. failing test first), and state a "
|
|
"step-by-step plan with per-step verification for multi-step work.",
|
|
]
|
|
|
|
def _generate_workflow_section(self) -> List[str]:
|
|
"""Generate workflow section based on specified workflows."""
|
|
lines = []
|
|
|
|
workflow_descriptions = {
|
|
'tdd': "1. **Test-Driven Development**: Write tests first, then implement features to pass tests",
|
|
'cicd': "2. **CI/CD**: All changes go through automated testing and deployment pipelines",
|
|
'documentation_first': "3. **Documentation First**: Document APIs and interfaces before implementation",
|
|
'agile': "4. **Agile Process**: Work in sprints with regular retrospectives and planning"
|
|
}
|
|
|
|
for i, workflow in enumerate(self.workflows, start=1):
|
|
if workflow in workflow_descriptions:
|
|
lines.append(workflow_descriptions[workflow])
|
|
else:
|
|
lines.append(f"{i}. **{workflow.replace('_', ' ').title()}**: [Add workflow description]")
|
|
|
|
return lines
|
|
|
|
def determine_complexity(self) -> str:
|
|
"""
|
|
Determine appropriate complexity level for the template.
|
|
|
|
Returns:
|
|
Complexity level: 'minimal', 'core', 'detailed', or 'comprehensive'
|
|
"""
|
|
team_config = self.TEAM_SIZE_TEMPLATES.get(self.team_size, self.TEAM_SIZE_TEMPLATES['small'])
|
|
return team_config['complexity']
|