diff --git a/apps/backend/spec/compaction.py b/apps/backend/spec/compaction.py index d74b377c..65365d34 100644 --- a/apps/backend/spec/compaction.py +++ b/apps/backend/spec/compaction.py @@ -141,7 +141,7 @@ def gather_phase_outputs(spec_dir: Path, phase_name: str) -> str: file_path = spec_dir / filename if file_path.exists(): try: - content = file_path.read_text() + content = file_path.read_text(encoding="utf-8") # Limit individual file size if len(content) > 10000: content = content[:10000] + "\n\n[... file truncated ...]" diff --git a/apps/backend/spec/pipeline/agent_runner.py b/apps/backend/spec/pipeline/agent_runner.py index d1ee2a78..b981a150 100644 --- a/apps/backend/spec/pipeline/agent_runner.py +++ b/apps/backend/spec/pipeline/agent_runner.py @@ -82,7 +82,7 @@ class AgentRunner: return False, f"Prompt not found: {prompt_path}" # Load prompt - prompt = prompt_path.read_text() + prompt = prompt_path.read_text(encoding="utf-8") debug_detailed( "agent_runner", "Loaded prompt file", diff --git a/apps/backend/spec/validate_pkg/validators/spec_document_validator.py b/apps/backend/spec/validate_pkg/validators/spec_document_validator.py index edf4a991..92a5f8ad 100644 --- a/apps/backend/spec/validate_pkg/validators/spec_document_validator.py +++ b/apps/backend/spec/validate_pkg/validators/spec_document_validator.py @@ -40,7 +40,12 @@ class SpecDocumentValidator: fixes.append("Create spec.md with required sections") return ValidationResult(False, "spec", errors, warnings, fixes) - content = spec_file.read_text() + try: + content = spec_file.read_text(encoding="utf-8") + except (OSError, UnicodeDecodeError) as e: + errors.append(f"Failed to read spec.md: {e}") + fixes.append("Ensure spec.md is a valid UTF-8 encoded file") + return ValidationResult(False, "spec", errors, warnings, fixes) # Check for required sections for section in SPEC_REQUIRED_SECTIONS: diff --git a/apps/backend/spec/validation_strategy.py b/apps/backend/spec/validation_strategy.py index cad467e2..fe71f8f1 100644 --- a/apps/backend/spec/validation_strategy.py +++ b/apps/backend/spec/validation_strategy.py @@ -171,9 +171,15 @@ def detect_project_type(project_dir: Path) -> str: # Try to detect API framework deps_text = "" if requirements.exists(): - deps_text = requirements.read_text().lower() + try: + deps_text = requirements.read_text(encoding="utf-8").lower() + except (OSError, UnicodeDecodeError): + pass # Skip if file is unreadable if pyproject.exists(): - deps_text += pyproject.read_text().lower() + try: + deps_text += pyproject.read_text(encoding="utf-8").lower() + except (OSError, UnicodeDecodeError): + pass # Skip if file is unreadable if "fastapi" in deps_text or "flask" in deps_text or "django" in deps_text: return "python_api"