From 3178ac8ddee5fa09ef8b5f00859b07ca34dfe08b Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 13:25:00 +0000 Subject: [PATCH] Add templates and MCP server modules --- src/contextgen/templates/engine.py | 346 +++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 src/contextgen/templates/engine.py diff --git a/src/contextgen/templates/engine.py b/src/contextgen/templates/engine.py new file mode 100644 index 0000000..86e2f35 --- /dev/null +++ b/src/contextgen/templates/engine.py @@ -0,0 +1,346 @@ +"""Template engine using Jinja2 for rendering.""" + +from pathlib import Path +from typing import Any + +from jinja2 import BaseLoader, Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError + + +class TemplateEngine: + """Jinja2-based template engine for rendering context output.""" + + BUILTIN_TEMPLATES = { + "minimal": """# Project Context + +## Overview +{{ project.name }} + +{{ project.description }} + +## Tech Stack +{% for lang, details in analysis.languages.items() %} +- {{ lang }}: {{ details.file_count }} files +{% endfor %} + +## Key Files +{% for file, desc in structure.key_files.items() %} +- {{ file }}: {{ desc }} +{% endfor %} +""", + "standard": """# Project Context + +## Overview +- **Project**: {{ project.name }} +- **Description**: {{ project.description }} +- **Primary Language**: {{ analysis.primary_language }} +- **Generated**: {{ timestamp }} + +## Tech Stack + +### Languages +{% for lang, details in analysis.languages.items() %} +- **{{ lang }}**: {{ details.file_count }} files +{% endfor %} + +### Frameworks +{% if analysis.frameworks %} +{% for fw in analysis.frameworks %} +- {{ fw.name }} (confidence: {{ (fw.confidence * 100)|round(1) }}%) +{% endfor %} +{% else %} +- No frameworks detected +{% endif %} + +### Build Tools +{% if analysis.build_tools %} +{% for tool in analysis.build_tools %} +- {{ tool.name }} (confidence: {{ (tool.confidence * 100)|round(1) }}%) +{% endfor %} +{% else %} +- No build tools detected +{% endif %} + +## Project Structure + +### Key Files +{% for file, desc in structure.key_files.items() %} +- `{{ file }}`: {{ desc }} +{% endfor %} + +### Directory Tree +``` +{% for dir, contents in structure.file_tree.directories.items() %} +{{ dir }} +{% for subdir, subcontents in contents.directories.items() %} + {{ subdir }} +{% endfor %} +{% endfor %} +``` + +## Coding Conventions + +### Naming Style +- **Functions**: {{ conventions.naming.functions.dominant }} +- **Classes**: {{ conventions.naming.classes.dominant }} +- **Variables**: {{ conventions.naming.variables.dominant }} +- **Files**: {{ conventions.naming.files.pattern }} + +### Code Style +- **Indentation**: {{ conventions.style.indentation.style }} ({{ conventions.style.indentation.width }} spaces) +- **Quote Style**: {{ conventions.style.quote_style.style }} +- **Line Endings**: {{ conventions.style.line_endings.style }} + +### Documentation +- **Style**: {{ conventions.documentation.style }} +- **Coverage**: {{ (conventions.documentation.documentation_coverage.ratio * 100)|round(1) }}% + +## Setup Instructions + +{% if setup.install_commands %} +### Installation +{% for cmd in setup.install_commands %} +``` +{{ cmd }} +``` +{% endfor %} +{% endif %} + +{% if setup.run_commands %} +### Running +{% for cmd in setup.run_commands %} +``` +{{ cmd }} +``` +{% endfor %} +{% endif %} + +{% if setup.test_commands %} +### Testing +{% for cmd in setup.test_commands %} +``` +{{ cmd }} +``` +{% endfor %} +{% endif %} + +{% if setup.environment_variables %} +### Environment Variables +{% for var in setup.environment_variables %} +- `{{ var }}` +{% endfor %} +{% endif %} +""", + "comprehensive": """# Project Context - Comprehensive Analysis + +## Metadata +- **Project Name**: {{ project.name }} +- **Description**: {{ project.description }} +- **Primary Language**: {{ analysis.primary_language }} +- **Total Files**: {{ structure.total_files }} +- **Total Directories**: {{ structure.total_dirs }} +- **Generated**: {{ timestamp }} + +--- + +## 1. Technology Stack + +### 1.1 Languages Detected +| Language | Files | Extensions | +|----------|-------|------------| +{% for lang, details in analysis.languages.items() %} +| {{ lang }} | {{ details.file_count }} | {{ details.extensions|join(', ') }} | +{% endfor %} + +### 1.2 Frameworks & Libraries +{% if analysis.frameworks %} +| Framework | Confidence | Indicators | +|-----------|------------|------------| +{% for fw in analysis.frameworks %} +| {{ fw.name }} | {{ (fw.confidence * 100)|round(1) }}% | {{ fw.indicators_found }} | +{% endfor %} +{% else %} +No frameworks detected. +{% endif %} + +### 1.3 Build Tools +{% if analysis.build_tools %} +| Tool | Confidence | +|------|------------| +{% for tool in analysis.build_tools %} +| {{ tool.name }} | {{ (tool.confidence * 100)|round(1) }}% | +{% endfor %} +{% else %} +No build tools detected. +{% endif %} + +### 1.4 Full Stack +{% if analysis.full_stack %} +- **Frontend**: {{ analysis.full_stack.frontend or 'Not detected' }} +- **Backend**: {{ analysis.full_stack.backend or 'Not detected' }} +{% else %} +No clear full stack detected. +{% endif %} + +--- + +## 2. Project Structure + +### 2.1 Key Files +| File | Description | +|------|-------------| +{% for file, desc in structure.key_files.items() %} +| `{{ file }}` | {{ desc }} | +{% endfor %} + +### 2.2 File Statistics +- **Total Files**: {{ structure.total_files }} +- **Total Directories**: {{ structure.total_dirs }} + +### 2.3 Directory Tree +``` +{{ project.path }} +{% for dir, contents in structure.file_tree.directories.items() %} +├── {{ dir }} +{% for subdir, subcontents in contents.directories.items() %} +│ ├── {{ subdir }} +{% endfor %} +{% endfor %} +``` + +--- + +## 3. Coding Conventions + +### 3.1 Naming Conventions +| Type | Dominant Style | Examples | +|------|----------------|----------| +| Functions | {{ conventions.naming.functions.dominant }} | {{ conventions.naming.functions.examples[:3]|join(', ') }} | +| Classes | {{ conventions.naming.classes.dominant }} | {{ conventions.naming.classes.examples[:3]|join(', ') }} | +| Variables | {{ conventions.naming.variables.dominant }} | {{ conventions.naming.variables.examples[:3]|join(', ') }} | +| Constants | {{ conventions.naming.constants.dominant }} | {{ conventions.naming.constants.examples[:3]|join(', ') }} | +| Files | {{ conventions.naming.files.pattern }} | {{ conventions.naming.files.examples[:3]|join(', ') }} | + +### 3.2 Code Style +| Aspect | Value | +|--------|-------| +| Indentation | {{ conventions.style.indentation.style }} ({{ conventions.style.indentation.width }} spaces) | +| Quote Style | {{ conventions.style.quote_style.style }} | +| Line Endings | {{ conventions.style.line_endings.style }} | +| Max Line Length | {{ conventions.style.max_line_length.max }} characters | +| Trailing Newline | {{ 'Yes' if conventions.style.trailing_newline.has_trailing_newline else 'No' }} | + +### 3.3 Documentation +| Aspect | Value | +|--------|-------| +| Docstring Style | {{ conventions.documentation.style }} | +| Coverage | {{ (conventions.documentation.documentation_coverage.ratio * 100)|round(1) }}% | +| Comment Style | {{ conventions.documentation.comment_style.dominant }} | + +--- + +## 4. Setup Instructions + +### 4.1 Installation +{% for cmd in setup.install_commands %} +```bash +{{ cmd }} +``` +{% endfor %} + +### 4.2 Build +{% for cmd in setup.build_commands %} +```bash +{{ cmd }} +``` +{% endfor %} + +### 4.3 Running +{% for cmd in setup.run_commands %} +```bash +{{ cmd }} +``` +{% endfor %} + +### 4.4 Testing +{% for cmd in setup.test_commands %} +```bash +{{ cmd }} +``` +{% endfor %} + +### 4.5 Environment Variables +{% for var in setup.environment_variables %} +- `{{ var }}` +{% endfor %} + +### 4.6 Notes +{% for note in setup.notes %} +- {{ note }} +{% endfor %} + +--- + +## 5. AI Assistant Tips + +When working with this codebase: + +1. **Naming**: The project uses {{ conventions.naming.dominant_style }} naming conventions. +2. **Documentation**: Docstrings follow {{ conventions.documentation.style }} style. +3. **Setup**: Run `{{ setup.install_commands[0] if setup.install_commands else 'appropriate install command' }}` to get started. +4. **Language**: Primary language is {{ analysis.primary_language }}. + +--- + +*Generated by Project Context Generator* +""", + } + + def __init__(self, template_path: Path | None = None): + self.template_path = template_path + self.env = self._create_environment() + + def _create_environment(self) -> Environment: + """Create Jinja2 environment.""" + if self.template_path and self.template_path.exists(): + loader: BaseLoader = FileSystemLoader(str(self.template_path)) + else: + loader = DummyLoader(self.BUILTIN_TEMPLATES) + + return Environment( + loader=loader, + trim_blocks=True, + lstrip_blocks=True, + ) + + def render( + self, template_name: str, context: dict[str, Any] + ) -> str: + """Render a template with the given context.""" + try: + template = self.env.get_template(template_name) + return template.render(**context) + except (TemplateSyntaxError, UndefinedError) as e: + raise ValueError(f"Template error: {e}") + + def get_available_templates(self) -> list[str]: + """Get list of available templates.""" + return list(self.BUILTIN_TEMPLATES.keys()) + + def list_templates(self) -> list[str]: + """List all available template names.""" + return self.get_available_templates() + + +class DummyLoader(BaseLoader): + """Dummy loader for builtin templates.""" + + def __init__(self, templates: dict[str, str]): + self.templates = templates + + def get_source(self, environment: Environment, template: str) -> tuple[str, str, None]: + if template in self.templates: + return self.templates[template], template, None + raise FileNotFoundError(f"Template {template} not found") + + def list_templates(self) -> list[str]: + return list(self.templates.keys())