Initial upload: CLI Explain Fix project with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-01-30 23:35:12 +00:00
parent bea039b0e4
commit e4e0097554

View File

@@ -0,0 +1,131 @@
"""Explanation generation module."""
from typing import Dict, Any, Optional
from cli_explain_fix.knowledge_base import KnowledgeBase, ErrorExplanation
from cli_explain_fix.parser import ParsedError
class Explainer:
"""Generator for human-readable error explanations."""
def __init__(self, knowledge_base: Optional[KnowledgeBase] = None):
"""Initialize explainer with optional knowledge base."""
self.knowledge_base = knowledge_base or KnowledgeBase()
def explain(self, parsed_error: ParsedError, verbose: bool = False) -> Dict[str, Any]:
"""Generate a complete explanation for a parsed error."""
explanation = self.knowledge_base.get_explanation(
parsed_error.error_type,
parsed_error.language
)
if not explanation:
explanation = self.knowledge_base.find_by_pattern(
parsed_error.message,
parsed_error.language
)
if not explanation:
explanation = self.knowledge_base.get_fallback_explanation(
parsed_error.error_type,
parsed_error.language
)
result: Dict[str, Any] = {
'error_type': parsed_error.error_type,
'language': parsed_error.language,
'summary': self._generate_summary(explanation),
'what_happened': explanation.what_happened,
'why_happened': explanation.why_happened,
'how_to_fix': explanation.how_to_fix,
'severity': explanation.severity,
}
if parsed_error.file_name:
result['location'] = {
'file': parsed_error.file_name,
'line': parsed_error.line_number,
}
if parsed_error.stack_frames:
result['stack_trace'] = parsed_error.stack_frames
if explanation.code_snippets:
code_examples = self._format_code_examples(explanation.code_snippets)
result['code_examples'] = code_examples
if explanation.documentation_url:
result['documentation'] = explanation.documentation_url
if verbose:
result['raw_error'] = parsed_error.raw_input
return result
def _generate_summary(self, explanation: ErrorExplanation) -> str:
"""Generate a short summary of the explanation."""
severity_icons = {
'critical': '🔴',
'high': '🟠',
'medium': '🟡',
'low': '🟢',
'unknown': '',
}
icon = severity_icons.get(explanation.severity, '')
return f"{icon} {explanation.error_type} in {explanation.language}"
def _format_code_examples(self, code_snippets: list) -> list:
"""Format code snippets for display."""
formatted = []
for snippet in code_snippets:
formatted.append({
'description': snippet.get('description', ''),
'code': snippet.get('code', ''),
'language': snippet.get('language', 'text'),
})
return formatted
def get_fix_steps(self, parsed_error: ParsedError) -> list:
"""Get step-by-step fix instructions."""
explanation = self.knowledge_base.get_explanation(
parsed_error.error_type,
parsed_error.language
)
if not explanation:
explanation = self.knowledge_base.get_fallback_explanation(
parsed_error.error_type,
parsed_error.language
)
return explanation.how_to_fix
def explain_simple(self, error_type: str, message: str, language: str) -> str:
"""Generate a simple text explanation."""
explanation = self.knowledge_base.get_explanation(error_type, language)
if not explanation:
explanation = self.knowledge_base.get_fallback_explanation(
error_type,
language
)
lines = [
f"Error: {error_type}",
f"Language: {language}",
"",
"What happened:",
explanation.what_happened,
"",
"Why it happened:",
explanation.why_happened,
"",
"How to fix:",
]
for i, step in enumerate(explanation.how_to_fix, 1):
lines.append(f" {i}. {step}")
return "\n".join(lines)