diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..16ddac3
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+GEMINI_API_KEY="YOUR_API_KEY_HERE"
diff --git a/.github/bug_report.md b/.github/bug_report.md
new file mode 100644
index 0000000..e5875b1
--- /dev/null
+++ b/.github/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug Report
+about: Create a report to help us improve
+title: "[BUG] "
+labels: bug
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/feature_request.md b/.github/feature_request.md
new file mode 100644
index 0000000..cdca565
--- /dev/null
+++ b/.github/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature Request
+about: Suggest an idea for this project
+title: "[FEATURE] "
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6acb60f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,117 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# Virtualenv
+venv/
+ENV/
+env/
+.venv/
+.env
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak
+venv.bak
+
+# IDEs
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..a7b4cf7
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,122 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that are welcoming, inclusive, and
+respectful.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+[INSERT CONTACT METHOD].
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interaction in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..71f7d4b
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,47 @@
+# Contributing to Singularity-AI
+
+First off, thank you for considering contributing to Singularity-AI! It's people like you that make the open-source community such a great place.
+
+We welcome any type of contribution, not only code. You can help with:
+* **Reporting a bug**
+* **Discussing the current state of the code**
+* **Submitting a fix**
+* **Proposing new features**
+* **Becoming a maintainer**
+
+## We Develop with Github
+We use Github to host code, to track issues and feature requests, as well as accept pull requests.
+
+## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
+Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests:
+
+1. Fork the repo and create your branch from `main`.
+2. If you've added code that should be tested, add tests.
+3. If you've changed APIs, update the documentation.
+4. Ensure the test suite passes.
+5. Make sure your code lints.
+6. Issue that pull request!
+
+## Any contributions you make will be under the MIT Software License
+In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
+
+## Report bugs using Github's [issues](https://github.com/briandk/transcriptase-atom/issues)
+We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy!
+
+## Write bug reports with detail, background, and sample code
+**Great Bug Reports** tend to have:
+- A quick summary and/or background
+- Steps to reproduce
+ - Be specific!
+ - Give sample code if you can.
+- What you expected would happen
+- What actually happens
+- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
+
+People *love* thorough bug reports. I'm not even kidding.
+
+## Use a Consistent Coding Style
+We don't have a strict style guide yet, but we try to follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) for Python code. Please try to follow the style of the existing code.
+
+## License
+By contributing, you agree that your contributions will be licensed under its MIT License.
diff --git a/README.md b/README.md
index 72bad52..aa1994a 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,109 @@
-# Singularity-AI
\ No newline at end of file
+
+
+ โพ๏ธ
+
+ Singularity-AI
+
+
+ Autonomous Software Engineering Assistant
+
+
+ Where AI meets infinity. Generate, test, debug, and deploy code with the power of generative AI.
+
+
+
+
+
+
+
+
+
+
+---
+
+## ๐ Introduction
+
+Singularity-AI is a powerful and intuitive Streamlit application that acts as an autonomous software engineering assistant. It leverages the capabilities of Google's Gemini large language model to provide a seamless experience for generating, testing, debugging, refactoring, and deploying software projects. Whether you're a seasoned developer looking to accelerate your workflow or a beginner learning to code, Singularity-AI is your go-to tool for building high-quality software.
+
+## โจ Features
+
+- **Project Generation:** Describe your project in natural language and watch as Singularity-AI generates a complete, multi-file project structure with production-ready code.
+- **Automated Testing:** Automatically run tests for your generated projects to ensure code quality and correctness.
+- **Autonomous Debugging:** If tests fail, Singularity-AI can autonomously analyze the errors and attempt to fix the code.
+- **Code Refactoring:** Refactor your code for readability, performance, size, or security with a single click.
+- **In-depth Code Analysis:** Get detailed explanations of your code, including complexity analysis and suggestions for improvement.
+- **Security Scanning:** Perform security analysis on your projects to identify and mitigate potential vulnerabilities.
+- **CI/CD and Deployment:** Generate CI/CD configurations for popular platforms like GitHub Actions and create deployment scripts for Docker, Kubernetes, and more.
+- **Interactive Dashboard:** Visualize project metrics, health scores, and quality trends over time.
+
+## ๐ ๏ธ Installation & Setup
+
+Follow these steps to get Singularity-AI up and running on your local machine.
+
+### 1. Clone the Repository
+
+```bash
+git clone https://github.com/your-username/Singularity-AI.git
+cd Singularity-AI
+```
+
+### 2. Create a Virtual Environment
+
+It's recommended to use a virtual environment to manage dependencies.
+
+```bash
+python -m venv venv
+source venv/bin/activate # On Windows, use `venv\Scripts\activate`
+```
+
+### 3. Install Dependencies
+
+Install the required Python packages using pip.
+
+```bash
+pip install -r requirements.txt
+```
+
+### 4. Set Up Your API Key
+
+Singularity-AI uses the Google Gemini API. You'll need to get an API key from the [Google AI Studio](https://aistudio.google.com/).
+
+Once you have your key, create a `.env` file in the root of the project directory by copying the example file:
+
+```bash
+cp .env.example .env
+```
+
+Now, open the `.env` file and add your Gemini API key:
+
+```
+GEMINI_API_KEY="YOUR_API_KEY_HERE"
+```
+
+## ๐โโ๏ธ How to Run
+
+With the setup complete, you can run the Streamlit application with a single command:
+
+```bash
+streamlit run src/main.py
+```
+
+This will start the application, and you can access it in your web browser at `http://localhost:8501`.
+
+## ๐ How to Use
+
+1. **Configure Your Project:** Use the sidebar to select the programming language and architecture pattern for your project.
+2. **Generate a Project:** In the "Generate" tab, describe the project you want to build and click "Generate Project".
+3. **Build and Test:** Once your project is generated, head to the "Build & Test" tab to run build commands and execute tests.
+4. **Analyze and Refactor:** Use the "Analysis" tab to get code explanations and the "Build & Test" tab to refactor your code.
+5. **Deploy:** In the "Deploy" tab, generate CI/CD configurations, Dockerfiles, and deployment scripts for your project.
+
+## ๐ Contributing
+
+Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
+
+Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for details on how to contribute to the project.
+
+## ๐ License
+
+This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
diff --git a/app.py b/app.py
deleted file mode 100644
index b744bcb..0000000
--- a/app.py
+++ /dev/null
@@ -1,1235 +0,0 @@
-import streamlit as st
-import google.generativeai as genai
-import os
-import tempfile
-import zipfile
-import subprocess
-import json
-import time
-import ast
-import re
-from pathlib import Path
-from typing import Dict, List, Tuple, Optional
-import pandas as pd
-import plotly.graph_objects as go
-import plotly.express as px
-from datetime import datetime
-import shutil
-
-# Page config
-st.set_page_config(
- page_title="Singularity-AI",
- page_icon="โพ๏ธ",
- layout="wide",
- initial_sidebar_state="expanded"
-)
-
-# Custom CSS for Singularity-AI theme
-st.markdown("""
-
-""", unsafe_allow_html=True)
-
-class CodeOracle:
- def __init__(self, api_key: str):
- self.api_key = api_key
- genai.configure(api_key=api_key)
- self.model = genai.GenerativeModel('gemini-2.5-flash')
- self.projects = {}
-
- def generate_project(self, prompt: str, language: str, architecture: str = "standard") -> Dict:
- """Generate a complete project from natural language prompt"""
-
- system_prompt = f"""
- You are CodeOracle, an expert software engineer. Generate a complete, production-ready {language} project based on the user's requirements.
-
- CRITICAL REQUIREMENTS:
- 1. Create a multi-file project structure with proper organization
- 2. Include all necessary files: source code, tests, README.md, requirements/package files, .gitignore
- 3. Write actual working code, not pseudocode or placeholders
- 4. Include comprehensive error handling and logging
- 5. Follow {language} best practices and conventions
- 6. Make the code modular and well-documented
- 7. Include unit tests and integration tests
- 8. Add security considerations where applicable
-
- Project Requirements: {prompt}
- Target Language: {language}
- Architecture Pattern: {architecture}
-
- Return the response as a JSON object with this exact structure:
- {{
- "project_name": "project-name",
- "description": "Brief project description",
- "files": {{
- "filename1.ext": "file content here",
- "filename2.ext": "file content here",
- "tests/test_file.ext": "test content here",
- "README.md": "comprehensive readme",
- ".gitignore": "appropriate gitignore for {language}"
- }},
- "dependencies": ["list", "of", "dependencies"],
- "build_commands": ["command1", "command2"],
- "run_commands": ["command1", "command2"],
- "test_commands": ["test command"],
- "architecture_notes": "explanation of the chosen architecture"
- }}
- """
-
- try:
- response = self.model.generate_content(system_prompt)
-
- # Parse JSON response
- json_start = response.text.find('{')
- json_end = response.text.rfind('}') + 1
- json_str = response.text[json_start:json_end]
-
- project_data = json.loads(json_str)
- return project_data
-
- except Exception as e:
- st.error(f"Generation failed: {str(e)}")
- return None
-
- def run_tests(self, project_path: str, language: str, test_commands: List[str]) -> Dict:
- """Run automated tests and return results"""
- results = {
- "success": False,
- "output": "",
- "errors": "",
- "coverage": 0,
- "failed_tests": []
- }
-
- try:
- os.chdir(project_path)
-
- for cmd in test_commands:
- process = subprocess.run(
- cmd.split(),
- capture_output=True,
- text=True,
- timeout=30
- )
-
- results["output"] += f"Command: {cmd}\n"
- results["output"] += process.stdout
-
- if process.returncode != 0:
- results["errors"] += process.stderr
- results["failed_tests"].append(cmd)
- else:
- results["success"] = True
-
- except subprocess.TimeoutExpired:
- results["errors"] = "Test execution timed out"
- except Exception as e:
- results["errors"] = str(e)
-
- return results
-
- def debug_and_fix(self, project_data: Dict, test_results: Dict, max_iterations: int = 3) -> Dict:
- """Autonomous debugging loop"""
-
- debug_prompt = f"""
- The following project has failing tests. Analyze the errors and fix the code:
-
- Project Structure: {list(project_data['files'].keys())}
- Test Errors: {test_results['errors']}
- Failed Commands: {test_results['failed_tests']}
-
- Current Code Files:
- {json.dumps(project_data['files'], indent=2)}
-
- Fix the issues and return the corrected files in the same JSON structure.
- Focus on:
- 1. Syntax errors
- 2. Import/dependency issues
- 3. Logic errors causing test failures
- 4. Missing error handling
-
- Return only the corrected files that need changes in this format:
- {{
- "fixed_files": {{
- "filename": "corrected content"
- }},
- "fix_explanation": "What was fixed and why"
- }}
- """
-
- try:
- response = self.model.generate_content(debug_prompt)
- json_start = response.text.find('{')
- json_end = response.text.rfind('}') + 1
- json_str = response.text[json_start:json_end]
-
- fix_data = json.loads(json_str)
-
- # Apply fixes
- for filename, content in fix_data.get("fixed_files", {}).items():
- project_data["files"][filename] = content
-
- return {
- "success": True,
- "explanation": fix_data.get("fix_explanation", ""),
- "updated_project": project_data
- }
-
- except Exception as e:
- return {"success": False, "error": str(e)}
-
- def refactor_code(self, project_data: Dict, refactor_type: str) -> Dict:
- """Refactor code for different objectives"""
-
- refactor_prompts = {
- "readability": "Refactor for maximum readability and maintainability",
- "performance": "Optimize for performance and efficiency",
- "size": "Minimize code size and bundle size",
- "security": "Enhance security and add security best practices"
- }
-
- prompt = f"""
- {refactor_prompts[refactor_type]} for this project:
-
- {json.dumps(project_data['files'], indent=2)}
-
- Return the refactored files in JSON format with explanations.
- """
-
- try:
- response = self.model.generate_content(prompt)
- # Parse and return refactored code
- return {"success": True, "refactored": response.text}
- except Exception as e:
- return {"success": False, "error": str(e)}
-
- def explain_code(self, code: str, language: str) -> str:
- """Provide detailed code explanation"""
-
- prompt = f"""
- Explain this {language} code line by line with:
- 1. What each function/class does
- 2. Time/space complexity analysis
- 3. Alternative approaches
- 4. How a senior developer would improve it
- 5. Potential issues or edge cases
-
- Code:
- {code}
- """
-
- try:
- response = self.model.generate_content(prompt)
- return response.text
- except Exception as e:
- return f"Explanation failed: {str(e)}"
-
- def security_scan(self, project_data: Dict, language: str) -> Dict:
- """Perform security analysis"""
-
- prompt = f"""
- Perform a comprehensive security analysis of this {language} project using OWASP guidelines:
-
- {json.dumps(project_data['files'], indent=2)}
-
- Identify:
- 1. Security vulnerabilities
- 2. Input validation issues
- 3. Authentication/authorization flaws
- 4. Data exposure risks
- 5. Dependency vulnerabilities
-
- Return findings with severity levels and suggested fixes.
- """
-
- try:
- response = self.model.generate_content(prompt)
- return {"success": True, "report": response.text}
- except Exception as e:
- return {"success": False, "error": str(e)}
-
- def generate_cicd(self, project_data: Dict, language: str, platform: str) -> str:
- """Generate CI/CD configuration"""
-
- prompt = f"""
- Generate {platform} CI/CD configuration for this {language} project:
-
- Project: {project_data['project_name']}
- Dependencies: {project_data['dependencies']}
- Build Commands: {project_data['build_commands']}
- Test Commands: {project_data['test_commands']}
-
- Include:
- 1. Build pipeline
- 2. Test automation
- 3. Security scanning
- 4. Deployment steps
- 5. Environment management
-
- Platform: {platform}
- """
-
- try:
- response = self.model.generate_content(prompt)
- return response.text
- except Exception as e:
- return f"CI/CD generation failed: {str(e)}"
-
-def create_project_files(project_data: Dict, base_path: str):
- """Create actual files from project data"""
- # Ensure base directory exists
- os.makedirs(base_path, exist_ok=True)
-
- for filename, content in project_data["files"].items():
- file_path = os.path.join(base_path, filename)
-
- # Create directory if filename contains subdirectories
- file_dir = os.path.dirname(file_path)
- if file_dir and file_dir != base_path:
- os.makedirs(file_dir, exist_ok=True)
-
- try:
- with open(file_path, 'w', encoding='utf-8') as f:
- f.write(content)
- except Exception as e:
- st.error(f"Failed to create file {filename}: {str(e)}")
- continue
-
-def create_zip_download(project_data: Dict) -> bytes:
- """Create downloadable zip file"""
- zip_buffer = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
-
- with zipfile.ZipFile(zip_buffer.name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
- for filename, content in project_data["files"].items():
- zip_file.writestr(filename, content)
-
- with open(zip_buffer.name, 'rb') as f:
- zip_data = f.read()
-
- os.unlink(zip_buffer.name)
- return zip_data
-
-# Initialize session state variables to prevent reruns
-def init_session_state():
- """Initialize all session state variables"""
- if 'oracle' not in st.session_state:
- st.session_state.oracle = None
- if 'current_project' not in st.session_state:
- st.session_state.current_project = None
- if 'test_results' not in st.session_state:
- st.session_state.test_results = None
- if 'generation_status' not in st.session_state:
- st.session_state.generation_status = None
- if 'build_output' not in st.session_state:
- st.session_state.build_output = None
- if 'security_report' not in st.session_state:
- st.session_state.security_report = None
- if 'cicd_configs' not in st.session_state:
- st.session_state.cicd_configs = {}
- if 'refactor_results' not in st.session_state:
- st.session_state.refactor_results = {}
- if 'explanations' not in st.session_state:
- st.session_state.explanations = {}
- if 'project_metrics' not in st.session_state:
- st.session_state.project_metrics = {}
-
-def main():
- # Initialize session state
- init_session_state()
-
- # Title and header with new theme
- st.markdown('โพ๏ธ Singularity-AI
', unsafe_allow_html=True)
- st.markdown('Where AI meets infinity โพ๏ธ
', unsafe_allow_html=True)
-
- # Sidebar configuration
- with st.sidebar:
- st.markdown("### โ๏ธ Configuration")
-
- # API Key input
- api_key = st.text_input(
- "๐ Gemini API Key",
- type="password",
- help="Enter your Google Gemini API key",
- key="api_key_input"
- )
-
- if not api_key:
- st.error("โ ๏ธ Please enter your Gemini API key to continue")
- st.stop()
-
- # Initialize CodeOracle only once
- if st.session_state.oracle is None:
- st.session_state.oracle = CodeOracle(api_key)
- st.success("โ
Singularity-AI Initialized!")
-
- # Language selection
- language = st.selectbox(
- "๐ป Programming Language",
- ["Python", "JavaScript", "TypeScript", "Go", "Rust", "Java", "Kotlin", "C++"],
- key="language_select"
- )
-
- # Architecture pattern
- architecture = st.selectbox(
- "๐๏ธ Architecture Pattern",
- ["Standard", "MVC", "Microservices", "Serverless", "Clean Architecture", "Hexagonal"],
- key="architecture_select"
- )
-
- # Advanced settings
- st.markdown("### ๐ฌ Advanced Settings")
- max_debug_iterations = st.slider("Max Debug Iterations", 1, 10, 3, key="debug_iter")
- auto_test = st.checkbox("Auto-run tests", value=True, key="auto_test")
- auto_debug = st.checkbox("Auto-debug failures", value=True, key="auto_debug")
-
- # Main interface tabs
- tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
- "๐ Generate", "๐ง Build & Test", "๐ Analysis", "๐ Dashboard", "๐ก๏ธ Security", "๐ Deploy"
- ])
-
- with tab1:
- st.markdown("### ๐ฏ Project Generator")
-
- # Project generation form
- col1, col2 = st.columns([3, 1])
-
- with col1:
- prompt = st.text_area(
- "๐ Describe your project:",
- #value=default_prompt,
- placeholder="Build a REST API for a todo app with user authentication, SQLite database, and CRUD operations",
- height=120,
- key="project_prompt"
- )
-
- with col2:
- template = st.selectbox(
- "โก Quick Templates",
- ["Custom", "Web App + Auth", "REST API", "ML Service", "CLI Tool", "Microservice"],
- key="template_select"
- )
-
- # Template auto-fill
- # Template auto-fill - set default value based on template
- template_prompts = {
- "Custom": "",
- "Web App + Auth": "Create a modern web application with user authentication, responsive design, and database integration",
- "REST API": "Build a RESTful API with CRUD operations, authentication, and comprehensive documentation",
- "ML Service": "Create a machine learning inference service with model loading, prediction endpoints, and monitoring",
- "CLI Tool": "Build a command-line tool with argument parsing, configuration management, and user-friendly output",
- "Microservice": "Create a microservice with health checks, logging, metrics, and containerization"
- }
-
- # Set the default prompt value based on template selection
- default_prompt = template_prompts.get(template, "")
-
- col1, col2 = st.columns(2)
- with col1:
- if st.button("๐งโโ๏ธ Generate Project", type="primary", key="generate_btn"):
- if prompt:
- with st.spinner("๐ฎ Singularity-AI is crafting your project..."):
- project_data = st.session_state.oracle.generate_project(prompt, language, architecture)
-
- if project_data:
- st.session_state.current_project = project_data
- st.session_state.generation_status = "success"
-
- # Calculate initial metrics
- total_lines = sum(len(content.split('\n')) for content in project_data['files'].values())
- st.session_state.project_metrics = {
- 'total_files': len(project_data['files']),
- 'total_lines': total_lines,
- 'avg_lines_per_file': round(total_lines/len(project_data['files'])),
- 'dependencies': len(project_data.get('dependencies', []))
- }
- else:
- st.session_state.generation_status = "error"
- else:
- st.error("โ ๏ธ Please provide a project description")
-
- # Display project overview (persistent)
- if st.session_state.current_project and st.session_state.generation_status == "success":
- project = st.session_state.current_project
-
- st.markdown('โจ Project generated successfully!
', unsafe_allow_html=True)
-
- st.markdown("### ๐ Project Overview")
- col1, col2 = st.columns(2)
-
- with col1:
- st.markdown(f"**๐ท๏ธ Name:** `{project['project_name']}`")
- st.markdown(f"**๐ป Language:** `{language}`")
- st.markdown(f"**๐ Files:** `{st.session_state.project_metrics['total_files']}`")
-
- with col2:
- st.markdown(f"**๐ฆ Dependencies:** `{st.session_state.project_metrics['dependencies']}`")
- st.markdown(f"**๐๏ธ Architecture:** `{architecture}`")
- st.markdown(f"**๐ Lines:** `{st.session_state.project_metrics['total_lines']}`")
-
- st.markdown(f"**๐ Description:** {project['description']}")
-
- # File browser
- st.markdown("### ๐ Generated Files")
- selected_file = st.selectbox(
- "View file:",
- list(project['files'].keys()),
- key="file_browser"
- )
-
- if selected_file:
- file_ext = selected_file.split('.')[-1] if '.' in selected_file else 'text'
- st.code(project['files'][selected_file], language=file_ext)
-
- # Download button
- col1, col2 = st.columns(2)
- with col1:
- zip_data = create_zip_download(project)
- st.download_button(
- label="๐ฆ Download Project ZIP",
- data=zip_data,
- file_name=f"{project['project_name']}.zip",
- mime="application/zip",
- key="download_zip"
- )
-
- with tab2:
- st.markdown("### ๐ง Build & Test Pipeline")
-
- if not st.session_state.current_project:
- st.markdown('โน๏ธ Generate a project first to see build and test options
', unsafe_allow_html=True)
- else:
- project = st.session_state.current_project
-
- col1, col2, col3 = st.columns(3)
-
- with col1:
- if st.button("๐จ Build Project", key="build_btn"):
- with st.spinner("๐๏ธ Building project..."):
- # Create temporary directory
- temp_dir = tempfile.mkdtemp()
- create_project_files(project, temp_dir)
-
- # Run build commands
- build_success = True
- build_output = ""
-
- for cmd in project.get('build_commands', []):
- try:
- result = subprocess.run(
- cmd.split(),
- cwd=temp_dir,
- capture_output=True,
- text=True,
- timeout=60
- )
- build_output += f"$ {cmd}\n{result.stdout}\n"
- if result.returncode != 0:
- build_success = False
- build_output += f"Error: {result.stderr}\n"
- except Exception as e:
- build_success = False
- build_output += f"Build failed: {str(e)}\n"
-
- st.session_state.build_output = {
- "success": build_success,
- "output": build_output
- }
-
- # Display build results (persistent)
- if st.session_state.build_output:
- if st.session_state.build_output["success"]:
- st.markdown('โ
Build successful!
', unsafe_allow_html=True)
- else:
- st.markdown('โ Build failed
', unsafe_allow_html=True)
-
- st.code(st.session_state.build_output["output"], language="bash")
-
- with col2:
- if st.button("๐งช Run Tests", key="test_btn"):
- with st.spinner("๐ฌ Running tests..."):
- temp_dir = tempfile.mkdtemp()
- create_project_files(project, temp_dir)
-
- test_results = st.session_state.oracle.run_tests(
- temp_dir,
- language,
- project.get('test_commands', [])
- )
-
- st.session_state.test_results = test_results
-
- # Display test results (persistent)
- if st.session_state.test_results:
- if st.session_state.test_results["success"]:
- st.markdown('โ
All tests passed!
', unsafe_allow_html=True)
- else:
- st.markdown('โ Some tests failed
', unsafe_allow_html=True)
-
- st.code(st.session_state.test_results["output"], language="bash")
-
- if st.session_state.test_results["errors"]:
- st.error("Test Errors:")
- st.code(st.session_state.test_results["errors"], language="bash")
-
- with col3:
- if st.button("๐ง Auto-Debug", key="debug_btn"):
- if st.session_state.test_results and not st.session_state.test_results["success"]:
- with st.spinner("๐ค Auto-debugging..."):
- debug_result = st.session_state.oracle.debug_and_fix(
- project,
- st.session_state.test_results,
- max_debug_iterations
- )
-
- if debug_result["success"]:
- st.session_state.current_project = debug_result["updated_project"]
- st.success("๐ง Auto-debug completed!")
- st.markdown(debug_result["explanation"])
- else:
- st.error(f"Auto-debug failed: {debug_result['error']}")
- else:
- st.info("No failing tests to debug")
-
- # Refactoring options
- st.markdown("### ๐ Refactoring Options")
- refactor_col1, refactor_col2, refactor_col3, refactor_col4 = st.columns(4)
-
- with refactor_col1:
- if st.button("๐ Readability", key="refactor_readability"):
- with st.spinner("๐ Refactoring for readability..."):
- result = st.session_state.oracle.refactor_code(project, "readability")
- if result["success"]:
- st.session_state.refactor_results["readability"] = result["refactored"]
-
- # Display readability refactor result (persistent)
- if "readability" in st.session_state.refactor_results:
- with st.expander("๐ Readability Refactor Result"):
- st.markdown(st.session_state.refactor_results["readability"])
-
- with refactor_col2:
- if st.button("โก Performance", key="refactor_performance"):
- with st.spinner("๐ Optimizing performance..."):
- result = st.session_state.oracle.refactor_code(project, "performance")
- if result["success"]:
- st.session_state.refactor_results["performance"] = result["refactored"]
-
- # Display performance refactor result (persistent)
- if "performance" in st.session_state.refactor_results:
- with st.expander("โก Performance Refactor Result"):
- st.markdown(st.session_state.refactor_results["performance"])
-
- with refactor_col3:
- if st.button("๐ฆ Size", key="refactor_size"):
- with st.spinner("๐ Minimizing size..."):
- result = st.session_state.oracle.refactor_code(project, "size")
- if result["success"]:
- st.session_state.refactor_results["size"] = result["refactored"]
-
- # Display size refactor result (persistent)
- if "size" in st.session_state.refactor_results:
- with st.expander("๐ฆ Size Refactor Result"):
- st.markdown(st.session_state.refactor_results["size"])
-
- with refactor_col4:
- if st.button("๐ก๏ธ Security", key="refactor_security"):
- with st.spinner("๐ Enhancing security..."):
- result = st.session_state.oracle.refactor_code(project, "security")
- if result["success"]:
- st.session_state.refactor_results["security"] = result["refactored"]
-
- # Display security refactor result (persistent)
- if "security" in st.session_state.refactor_results:
- with st.expander("๐ก๏ธ Security Refactor Result"):
- st.markdown(st.session_state.refactor_results["security"])
-
- with tab3:
- st.markdown("### ๐ Code Analysis & Insights")
-
- if not st.session_state.current_project:
- st.markdown('โน๏ธ Generate a project first to see analysis options
', unsafe_allow_html=True)
- else:
- project = st.session_state.current_project
-
- # Code explanation
- st.markdown("### ๐ Explain Code")
- explain_file = st.selectbox(
- "Select file to explain:",
- list(project['files'].keys()),
- key="explain_file_select"
- )
-
- if st.button("๐ Explain This File", key="explain_btn"):
- with st.spinner("๐ง Analyzing code..."):
- explanation = st.session_state.oracle.explain_code(
- project['files'][explain_file],
- language
- )
- st.session_state.explanations[explain_file] = explanation
-
- # Display explanation (persistent)
- if explain_file in st.session_state.explanations:
- with st.expander(f"๐ Explanation: {explain_file}"):
- st.markdown(st.session_state.explanations[explain_file])
-
- # Architecture visualization
- st.markdown("### ๐๏ธ Architecture Overview")
-
- col1, col2 = st.columns(2)
- with col1:
- if st.button("๐ Visualize Architecture", key="viz_arch_btn"):
- # Create a simple architecture diagram
- files = list(project['files'].keys())
- file_types = {}
-
- for file in files:
- ext = file.split('.')[-1] if '.' in file else 'other'
- file_types[ext] = file_types.get(ext, 0) + 1
-
- # Store visualization data in session state
- st.session_state.arch_viz_data = file_types
-
- # Display architecture visualization (persistent)
- if hasattr(st.session_state, 'arch_viz_data'):
- # Create pie chart of file types
- fig = px.pie(
- values=list(st.session_state.arch_viz_data.values()),
- names=list(st.session_state.arch_viz_data.keys()),
- title="Project File Distribution",
- color_discrete_sequence=px.colors.qualitative.Set3
- )
- fig.update_layout(
- plot_bgcolor='rgba(0,0,0,0)',
- paper_bgcolor='rgba(0,0,0,0)',
- font_color='white'
- )
- st.plotly_chart(fig, use_container_width=True)
-
- # Dependency graph (simplified)
- st.markdown("### ๐ฆ Dependencies")
- deps = project.get('dependencies', [])
- if deps:
- dep_df = pd.DataFrame({'Dependency': deps, 'Type': ['External'] * len(deps)})
- st.dataframe(dep_df, use_container_width=True)
- else:
- st.info("No external dependencies found")
-
- # Code metrics
- st.markdown("### ๐ Code Metrics")
-
- st.markdown("### ๐ Code Metrics")
-
- if hasattr(st.session_state, 'project_metrics') and st.session_state.project_metrics:
- metrics = st.session_state.project_metrics
- col1, col2, col3, col4 = st.columns(4)
- col1.metric("Total Files", metrics['total_files'])
- col2.metric("Total Lines", metrics['total_lines'])
- col3.metric("Avg Lines/File", metrics['avg_lines_per_file'])
- col4.metric("Dependencies", metrics['dependencies'])
- elif st.session_state.current_project:
- # Fallback calculation if metrics not available
- project = st.session_state.current_project
- total_files = len(project['files'])
- total_lines = sum(len(content.split('\n')) for content in project['files'].values())
- avg_lines = round(total_lines/total_files) if total_files > 0 else 0
- dependencies = len(project.get('dependencies', []))
-
- col1, col2, col3, col4 = st.columns(4)
- col1.metric("Total Files", total_files)
- col2.metric("Total Lines", total_lines)
- col3.metric("Avg Lines/File", avg_lines)
- col4.metric("Dependencies", dependencies)
-
- with tab4:
- st.markdown("### ๐ Project Health Dashboard")
-
- if not st.session_state.current_project:
- st.markdown('โน๏ธ Generate a project first to see the dashboard
', unsafe_allow_html=True)
- else:
- project = st.session_state.current_project
-
- # Health score calculation (mock)
- health_score = 85 # This would be calculated based on various metrics
-
- col1, col2, col3 = st.columns(3)
-
- with col1:
- st.metric("๐ฅ Health Score", f"{health_score}%", "5%")
- with col2:
- test_coverage = "78%" if st.session_state.test_results and st.session_state.test_results["success"] else "0%"
- st.metric("๐งช Test Coverage", test_coverage, "12%")
- with col3:
- security_rating = "A-" if "security" in st.session_state.refactor_results else "C"
- st.metric("๐ก๏ธ Security Rating", security_rating, "0")
-
- # Project timeline (mock data)
- st.markdown("### ๐ Project Timeline")
- timeline_events = []
- if st.session_state.current_project:
- timeline_events.append(('Generated', datetime.now().strftime('%H:%M:%S'), 'โ
'))
- if st.session_state.build_output:
- status = 'โ
' if st.session_state.build_output["success"] else 'โ'
- timeline_events.append(('Built', datetime.now().strftime('%H:%M:%S'), status))
- if st.session_state.test_results:
- status = 'โ
' if st.session_state.test_results["success"] else 'โ'
- timeline_events.append(('Tested', datetime.now().strftime('%H:%M:%S'), status))
- if st.session_state.security_report:
- timeline_events.append(('Secured', datetime.now().strftime('%H:%M:%S'), 'โ
'))
-
- if timeline_events:
- timeline_data = pd.DataFrame(timeline_events, columns=['Event', 'Timestamp', 'Status'])
- st.dataframe(timeline_data, use_container_width=True)
-
- # Code quality trends (mock chart)
- st.markdown("### ๐ Quality Trends")
-
- # Generate mock trend data
- dates = pd.date_range(start='2024-01-01', end='2024-12-31', freq='M')
- quality_data = pd.DataFrame({
- 'Date': dates,
- 'Code Quality': [75 + i*2 + (i%3)*5 for i in range(len(dates))],
- 'Test Coverage': [60 + i*1.5 + (i%2)*3 for i in range(len(dates))],
- 'Security Score': [70 + i*1.8 + (i%4)*4 for i in range(len(dates))]
- })
-
- fig = px.line(
- quality_data,
- x='Date',
- y=['Code Quality', 'Test Coverage', 'Security Score'],
- title="Project Health Over Time"
- )
- fig.update_layout(
- plot_bgcolor='rgba(0,0,0,0)',
- paper_bgcolor='rgba(0,0,0,0)',
- font_color='white'
- )
- st.plotly_chart(fig, use_container_width=True)
-
- with tab5:
- st.markdown("### ๐ก๏ธ Security Analysis")
-
- if not st.session_state.current_project:
- st.markdown('โน๏ธ Generate a project first to run security analysis
', unsafe_allow_html=True)
- else:
- project = st.session_state.current_project
-
- if st.button("๐ Run Security Scan", key="security_scan_btn"):
- with st.spinner("๐ก๏ธ Scanning for security vulnerabilities..."):
- security_result = st.session_state.oracle.security_scan(project, language)
- st.session_state.security_report = security_result
-
- # Display security report (persistent)
- if st.session_state.security_report:
- if st.session_state.security_report["success"]:
- st.markdown("### ๐ก๏ธ Security Report")
- st.markdown(st.session_state.security_report["report"])
- else:
- st.error(f"Security scan failed: {st.session_state.security_report['error']}")
-
- # Security checklist
- st.markdown("### โ
Security Checklist")
-
- security_items = [
- "Input validation implemented",
- "Authentication mechanisms in place",
- "Authorization checks present",
- "SQL injection prevention",
- "XSS protection enabled",
- "CSRF tokens implemented",
- "Secure headers configured",
- "Dependency vulnerabilities checked"
- ]
-
- for i, item in enumerate(security_items):
- st.checkbox(item, value=False, key=f"security_check_{i}")
-
- with tab6:
- st.markdown("### ๐ Deployment & CI/CD")
-
- if not st.session_state.current_project:
- st.markdown('โน๏ธ Generate a project first to see deployment options
', unsafe_allow_html=True)
- else:
- project = st.session_state.current_project
-
- # CI/CD platform selection
- col1, col2 = st.columns(2)
-
- with col1:
- st.markdown("### ๐ CI/CD Configuration")
- cicd_platform = st.selectbox(
- "Platform:",
- ["GitHub Actions", "GitLab CI", "CircleCI", "Jenkins"],
- key="cicd_platform_select"
- )
-
- if st.button("Generate CI/CD Config", key="generate_cicd_btn"):
- with st.spinner("โ๏ธ Generating CI/CD configuration..."):
- cicd_config = st.session_state.oracle.generate_cicd(
- project, language, cicd_platform
- )
- st.session_state.cicd_configs[cicd_platform] = cicd_config
-
- # Display CI/CD config (persistent)
- if cicd_platform in st.session_state.cicd_configs:
- st.code(st.session_state.cicd_configs[cicd_platform], language="yaml")
-
- # Download CI/CD config
- st.download_button(
- label="๐ฅ Download CI/CD Config",
- data=st.session_state.cicd_configs[cicd_platform],
- file_name=f"{cicd_platform.lower().replace(' ', '_')}.yml",
- mime="text/yaml",
- key=f"download_cicd_{cicd_platform}"
- )
-
- with col2:
- st.markdown("### ๐ณ Containerization")
-
- if st.button("Generate Dockerfile", key="generate_dockerfile_btn"):
- dockerfile_prompt = f"""
- Generate a production-ready Dockerfile for this {language} project:
-
- Project: {project['project_name']}
- Dependencies: {project.get('dependencies', [])}
- Build Commands: {project.get('build_commands', [])}
- Run Commands: {project.get('run_commands', [])}
-
- Include:
- - Multi-stage build
- - Security best practices
- - Optimized layer caching
- - Non-root user
- - Health checks
- """
-
- with st.spinner("๐ณ Generating Dockerfile..."):
- try:
- response = st.session_state.oracle.model.generate_content(dockerfile_prompt)
- st.session_state.dockerfile_content = response.text
- except Exception as e:
- st.error(f"Dockerfile generation failed: {str(e)}")
-
- # Display Dockerfile (persistent)
- if hasattr(st.session_state, 'dockerfile_content'):
- st.code(st.session_state.dockerfile_content, language="dockerfile")
-
- st.download_button(
- label="๐ฅ Download Dockerfile",
- data=st.session_state.dockerfile_content,
- file_name="Dockerfile",
- mime="text/plain",
- key="download_dockerfile"
- )
-
- # Deployment scripts
- st.markdown("### ๐ Deployment Scripts")
-
- deployment_type = st.selectbox(
- "Deployment Target:",
- ["Docker Compose", "Kubernetes", "AWS ECS", "Google Cloud Run", "Azure Container Apps"],
- key="deployment_type_select"
- )
-
- if st.button("Generate Deployment Script", key="generate_deploy_btn"):
- deploy_prompt = f"""
- Generate deployment configuration for {deployment_type} for this project:
-
- Project: {project['project_name']}
- Language: {language}
- Dependencies: {project.get('dependencies', [])}
- Build Commands: {project.get('build_commands', [])}
- Run Commands: {project.get('run_commands', [])}
-
- Include:
- - Service definitions
- - Environment variables
- - Resource limits
- - Health checks
- - Networking configuration
- - Scaling policies
- - Monitoring setup
- """
-
- with st.spinner(f"๐ Generating {deployment_type} configuration..."):
- try:
- response = st.session_state.oracle.model.generate_content(deploy_prompt)
- if 'deploy_configs' not in st.session_state:
- st.session_state.deploy_configs = {}
- st.session_state.deploy_configs[deployment_type] = response.text
- except Exception as e:
- st.error(f"Deployment configuration generation failed: {str(e)}")
-
- # Display deployment config (persistent)
- if hasattr(st.session_state, 'deploy_configs') and deployment_type in st.session_state.deploy_configs:
- st.code(st.session_state.deploy_configs[deployment_type], language="yaml")
-
- # Determine file extension based on deployment type
- file_extensions = {
- "Docker Compose": "docker-compose.yml",
- "Kubernetes": "k8s-deployment.yaml",
- "AWS ECS": "ecs-task-definition.json",
- "Google Cloud Run": "cloudrun-service.yaml",
- "Azure Container Apps": "containerapp.yaml"
- }
-
- filename = file_extensions.get(deployment_type, "deployment.yaml")
-
- st.download_button(
- label=f"๐ฅ Download {deployment_type} Config",
- data=st.session_state.deploy_configs[deployment_type],
- file_name=filename,
- mime="text/yaml",
- key=f"download_deploy_{deployment_type}"
- )
-
- # Environment management
- st.markdown("### ๐ง Environment Configuration")
-
- env_type = st.selectbox(
- "Environment Type:",
- ["Development", "Staging", "Production"],
- key="env_type_select"
- )
-
- if st.button("Generate Environment Config", key="generate_env_btn"):
- env_prompt = f"""
- Generate environment configuration for {env_type} environment:
-
- Project: {project['project_name']}
- Language: {language}
-
- Include appropriate settings for {env_type}:
- - Environment variables
- - Database configurations
- - Logging levels
- - Security settings
- - Performance optimizations
- - Monitoring configurations
- """
-
- with st.spinner(f"โ๏ธ Generating {env_type} environment config..."):
- try:
- response = st.session_state.oracle.model.generate_content(env_prompt)
- if 'env_configs' not in st.session_state:
- st.session_state.env_configs = {}
- st.session_state.env_configs[env_type] = response.text
- except Exception as e:
- st.error(f"Environment configuration generation failed: {str(e)}")
-
- # Display environment config (persistent)
- if hasattr(st.session_state, 'env_configs') and env_type in st.session_state.env_configs:
- st.code(st.session_state.env_configs[env_type], language="bash")
-
- st.download_button(
- label=f"๐ฅ Download {env_type} Config",
- data=st.session_state.env_configs[env_type],
- file_name=f".env.{env_type.lower()}",
- mime="text/plain",
- key=f"download_env_{env_type}"
- )
-
- # Footer with new theme
- st.markdown("---")
- st.markdown(
- """
-
-
โพ๏ธ Singularity-AI - Where AI meets infinity
-
Autonomous Software Engineering Assistant
-
Powered by Google Gemini โข Built with Streamlit โข Enhanced with infinite possibilities
-
โพ๏ธ
-
- """,
- unsafe_allow_html=True
- )
-
-if __name__ == "__main__":
- main()
diff --git a/requirements.txt b/requirements.txt
index 0de3097..0c7b718 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,3 +2,4 @@ streamlit
google-generativeai
pandas
plotly
+python-dotenv
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..1b464b5
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Install dependencies
+pip install -r requirements.txt
+
+# Run the Streamlit application
+streamlit run src/main.py
diff --git a/src/code_oracle.py b/src/code_oracle.py
new file mode 100644
index 0000000..23b34cd
--- /dev/null
+++ b/src/code_oracle.py
@@ -0,0 +1,251 @@
+import streamlit as st
+import google.generativeai as genai
+import os
+import subprocess
+import json
+from typing import Dict, List
+
+class CodeOracle:
+ def __init__(self, api_key: str):
+ self.api_key = api_key
+ genai.configure(api_key=api_key)
+ self.model = genai.GenerativeModel('gemini-2.5-flash')
+ self.projects = {}
+
+ def generate_project(self, prompt: str, language: str, architecture: str = "standard") -> Dict:
+ """Generate a complete project from natural language prompt"""
+
+ system_prompt = f"""
+ You are CodeOracle, an expert software engineer. Generate a complete, production-ready {language} project based on the user's requirements.
+
+ CRITICAL REQUIREMENTS:
+ 1. Create a multi-file project structure with proper organization
+ 2. Include all necessary files: source code, tests, README.md, requirements/package files, .gitignore
+ 3. Write actual working code, not pseudocode or placeholders
+ 4. Include comprehensive error handling and logging
+ 5. Follow {language} best practices and conventions
+ 6. Make the code modular and well-documented
+ 7. Include unit tests and integration tests
+ 8. Add security considerations where applicable
+
+ Project Requirements: {prompt}
+ Target Language: {language}
+ Architecture Pattern: {architecture}
+
+ Return the response as a JSON object with this exact structure:
+ {{
+ "project_name": "project-name",
+ "description": "Brief project description",
+ "files": {{
+ "filename1.ext": "file content here",
+ "filename2.ext": "file content here",
+ "tests/test_file.ext": "test content here",
+ "README.md": "comprehensive readme",
+ ".gitignore": "appropriate gitignore for {language}"
+ }},
+ "dependencies": ["list", "of", "dependencies"],
+ "build_commands": ["command1", "command2"],
+ "run_commands": ["command1", "command2"],
+ "test_commands": ["test command"],
+ "architecture_notes": "explanation of the chosen architecture"
+ }}
+ """
+
+ try:
+ response = self.model.generate_content(system_prompt)
+
+ # Parse JSON response
+ json_start = response.text.find('{')
+ json_end = response.text.rfind('}') + 1
+ json_str = response.text[json_start:json_end]
+
+ project_data = json.loads(json_str)
+ return project_data
+
+ except Exception as e:
+ st.error(f"Generation failed: {str(e)}")
+ return None
+
+ def run_tests(self, project_path: str, language: str, test_commands: List[str]) -> Dict:
+ """Run automated tests and return results"""
+ results = {
+ "success": False,
+ "output": "",
+ "errors": "",
+ "coverage": 0,
+ "failed_tests": []
+ }
+
+ try:
+ os.chdir(project_path)
+
+ for cmd in test_commands:
+ process = subprocess.run(
+ cmd.split(),
+ capture_output=True,
+ text=True,
+ timeout=30
+ )
+
+ results["output"] += f"Command: {cmd}\n"
+ results["output"] += process.stdout
+
+ if process.returncode != 0:
+ results["errors"] += process.stderr
+ results["failed_tests"].append(cmd)
+ else:
+ results["success"] = True
+
+ except subprocess.TimeoutExpired:
+ results["errors"] = "Test execution timed out"
+ except Exception as e:
+ results["errors"] = str(e)
+
+ return results
+
+ def debug_and_fix(self, project_data: Dict, test_results: Dict, max_iterations: int = 3) -> Dict:
+ """Autonomous debugging loop"""
+
+ debug_prompt = f"""
+ The following project has failing tests. Analyze the errors and fix the code:
+
+ Project Structure: {list(project_data['files'].keys())}
+ Test Errors: {test_results['errors']}
+ Failed Commands: {test_results['failed_tests']}
+
+ Current Code Files:
+ {json.dumps(project_data['files'], indent=2)}
+
+ Fix the issues and return the corrected files in the same JSON structure.
+ Focus on:
+ 1. Syntax errors
+ 2. Import/dependency issues
+ 3. Logic errors causing test failures
+ 4. Missing error handling
+
+ Return only the corrected files that need changes in this format:
+ {{
+ "fixed_files": {{
+ "filename": "corrected content"
+ }},
+ "fix_explanation": "What was fixed and why"
+ }}
+ """
+
+ try:
+ response = self.model.generate_content(debug_prompt)
+ json_start = response.text.find('{')
+ json_end = response.text.rfind('}') + 1
+ json_str = response.text[json_start:json_end]
+
+ fix_data = json.loads(json_str)
+
+ # Apply fixes
+ for filename, content in fix_data.get("fixed_files", {}).items():
+ project_data["files"][filename] = content
+
+ return {
+ "success": True,
+ "explanation": fix_data.get("fix_explanation", ""),
+ "updated_project": project_data
+ }
+
+ except Exception as e:
+ return {"success": False, "error": str(e)}
+
+ def refactor_code(self, project_data: Dict, refactor_type: str) -> Dict:
+ """Refactor code for different objectives"""
+
+ refactor_prompts = {
+ "readability": "Refactor for maximum readability and maintainability",
+ "performance": "Optimize for performance and efficiency",
+ "size": "Minimize code size and bundle size",
+ "security": "Enhance security and add security best practices"
+ }
+
+ prompt = f"""
+ {refactor_prompts[refactor_type]} for this project:
+
+ {json.dumps(project_data['files'], indent=2)}
+
+ Return the refactored files in JSON format with explanations.
+ """
+
+ try:
+ response = self.model.generate_content(prompt)
+ # Parse and return refactored code
+ return {"success": True, "refactored": response.text}
+ except Exception as e:
+ return {"success": False, "error": str(e)}
+
+ def explain_code(self, code: str, language: str) -> str:
+ """Provide detailed code explanation"""
+
+ prompt = f"""
+ Explain this {language} code line by line with:
+ 1. What each function/class does
+ 2. Time/space complexity analysis
+ 3. Alternative approaches
+ 4. How a senior developer would improve it
+ 5. Potential issues or edge cases
+
+ Code:
+ {code}
+ """
+
+ try:
+ response = self.model.generate_content(prompt)
+ return response.text
+ except Exception as e:
+ return f"Explanation failed: {str(e)}"
+
+ def security_scan(self, project_data: Dict, language: str) -> Dict:
+ """Perform security analysis"""
+
+ prompt = f"""
+ Perform a comprehensive security analysis of this {language} project using OWASP guidelines:
+
+ {json.dumps(project_data['files'], indent=2)}
+
+ Identify:
+ 1. Security vulnerabilities
+ 2. Input validation issues
+ 3. Authentication/authorization flaws
+ 4. Data exposure risks
+ 5. Dependency vulnerabilities
+
+ Return findings with severity levels and suggested fixes.
+ """
+
+ try:
+ response = self.model.generate_content(prompt)
+ return {"success": True, "report": response.text}
+ except Exception as e:
+ return {"success": False, "error": str(e)}
+
+ def generate_cicd(self, project_data: Dict, language: str, platform: str) -> str:
+ """Generate CI/CD configuration"""
+
+ prompt = f"""
+ Generate {platform} CI/CD configuration for this {language} project:
+
+ Project: {project_data['project_name']}
+ Dependencies: {project_data['dependencies']}
+ Build Commands: {project_data['build_commands']}
+ Test Commands: {project_data['test_commands']}
+
+ Include:
+ 1. Build pipeline
+ 2. Test automation
+ 3. Security scanning
+ 4. Deployment steps
+ 5. Environment management
+
+ Platform: {platform}
+ """
+
+ try:
+ response = self.model.generate_content(prompt)
+ return response.text
+ except Exception as e:
+ return f"CI/CD generation failed: {str(e)}"
diff --git a/src/main.py b/src/main.py
new file mode 100644
index 0000000..6b97a1d
--- /dev/null
+++ b/src/main.py
@@ -0,0 +1,145 @@
+import streamlit as st
+import os
+import tempfile
+import subprocess
+from dotenv import load_dotenv
+from src.code_oracle import CodeOracle
+from src.ui import (
+ setup_page_config,
+ load_custom_css,
+ render_sidebar,
+ render_main_content,
+ render_generate_tab,
+ render_project_overview,
+ render_build_test_tab,
+ render_analysis_tab,
+ render_dashboard_tab,
+ render_security_tab,
+ render_deploy_tab,
+ render_footer
+)
+from src.utils import create_project_files
+
+def init_session_state():
+ """Initialize all session state variables"""
+ if 'oracle' not in st.session_state:
+ st.session_state.oracle = None
+ if 'current_project' not in st.session_state:
+ st.session_state.current_project = None
+ if 'test_results' not in st.session_state:
+ st.session_state.test_results = None
+ if 'generation_status' not in st.session_state:
+ st.session_state.generation_status = None
+ if 'build_output' not in st.session_state:
+ st.session_state.build_output = None
+ if 'security_report' not in st.session_state:
+ st.session_state.security_report = None
+ if 'cicd_configs' not in st.session_state:
+ st.session_state.cicd_configs = {}
+ if 'refactor_results' not in st.session_state:
+ st.session_state.refactor_results = {}
+ if 'explanations' not in st.session_state:
+ st.session_state.explanations = {}
+ if 'project_metrics' not in st.session_state:
+ st.session_state.project_metrics = {}
+
+def main():
+ load_dotenv()
+ init_session_state()
+ setup_page_config()
+ load_custom_css()
+
+ language, architecture, max_debug_iterations, auto_test, auto_debug = render_sidebar()
+
+ api_key = os.getenv("GEMINI_API_KEY")
+ if not api_key:
+ st.error("โ ๏ธ Please set your GEMINI_API_KEY in a .env file to continue")
+ st.stop()
+
+ if st.session_state.oracle is None:
+ st.session_state.oracle = CodeOracle(api_key)
+ st.success("โ
Singularity-AI Initialized!")
+
+ tab1, tab2, tab3, tab4, tab5, tab6 = render_main_content()
+
+ with tab1:
+ prompt = render_generate_tab(language, architecture)
+ if prompt:
+ with st.spinner("๐ฎ Singularity-AI is crafting your project..."):
+ project_data = st.session_state.oracle.generate_project(prompt, language, architecture)
+ if project_data:
+ st.session_state.current_project = project_data
+ st.session_state.generation_status = "success"
+ total_lines = sum(len(content.split('\n')) for content in project_data['files'].values())
+ st.session_state.project_metrics = {
+ 'total_files': len(project_data['files']),
+ 'total_lines': total_lines,
+ 'avg_lines_per_file': round(total_lines / len(project_data['files'])) if project_data.get('files') else 0,
+ 'dependencies': len(project_data.get('dependencies', []))
+ }
+ else:
+ st.session_state.generation_status = "error"
+
+ render_project_overview(language, architecture)
+
+ with tab2:
+ action = render_build_test_tab(language, max_debug_iterations)
+ if action == "build":
+ with st.spinner("๐๏ธ Building project..."):
+ temp_dir = tempfile.mkdtemp()
+ create_project_files(st.session_state.current_project, temp_dir)
+ build_success = True
+ build_output = ""
+ for cmd in st.session_state.current_project.get('build_commands', []):
+ try:
+ result = subprocess.run(cmd.split(), cwd=temp_dir, capture_output=True, text=True, timeout=60)
+ build_output += f"$ {cmd}\n{result.stdout}\n"
+ if result.returncode != 0:
+ build_success = False
+ build_output += f"Error: {result.stderr}\n"
+ except Exception as e:
+ build_success = False
+ build_output += f"Build failed: {str(e)}\n"
+ st.session_state.build_output = {"success": build_success, "output": build_output}
+ elif action == "test":
+ with st.spinner("๐ฌ Running tests..."):
+ temp_dir = tempfile.mkdtemp()
+ create_project_files(st.session_state.current_project, temp_dir)
+ test_results = st.session_state.oracle.run_tests(temp_dir, language, st.session_state.current_project.get('test_commands', []))
+ st.session_state.test_results = test_results
+ elif action == "debug":
+ with st.spinner("๐ค Auto-debugging..."):
+ debug_result = st.session_state.oracle.debug_and_fix(st.session_state.current_project, st.session_state.test_results, max_debug_iterations)
+ if debug_result["success"]:
+ st.session_state.current_project = debug_result["updated_project"]
+ st.success("๐ง Auto-debug completed!")
+ st.markdown(debug_result["explanation"])
+ else:
+ st.error(f"Auto-debug failed: {debug_result['error']}")
+ elif action and action.startswith("refactor"):
+ refactor_type = action.split("_")[1]
+ with st.spinner(f"๐ Refactoring for {refactor_type}..."):
+ result = st.session_state.oracle.refactor_code(st.session_state.current_project, refactor_type)
+ if result["success"]:
+ st.session_state.refactor_results[refactor_type] = result["refactored"]
+
+ with tab3:
+ render_analysis_tab(language)
+
+ with tab4:
+ render_dashboard_tab()
+
+ with tab5:
+ action = render_security_tab(language)
+ if action == "scan":
+ with st.spinner("๐ก๏ธ Scanning for security vulnerabilities..."):
+ security_result = st.session_state.oracle.security_scan(st.session_state.current_project, language)
+ st.session_state.security_report = security_result
+
+ with tab6:
+ render_deploy_tab(language)
+
+ render_footer()
+
+if __name__ == "__main__":
+ main()
diff --git a/src/ui.py b/src/ui.py
new file mode 100644
index 0000000..edcd795
--- /dev/null
+++ b/src/ui.py
@@ -0,0 +1,761 @@
+import streamlit as st
+import pandas as pd
+import plotly.express as px
+from datetime import datetime
+from src.utils import create_zip_download
+
+def setup_page_config():
+ st.set_page_config(
+ page_title="Singularity-AI",
+ page_icon="โพ๏ธ",
+ layout="wide",
+ initial_sidebar_state="expanded"
+ )
+
+def load_custom_css():
+ st.markdown("""
+
+ """, unsafe_allow_html=True)
+
+def render_sidebar():
+ with st.sidebar:
+ st.markdown("### โ๏ธ Configuration")
+
+ # Language selection
+ language = st.selectbox(
+ "๐ป Programming Language",
+ ["Python", "JavaScript", "TypeScript", "Go", "Rust", "Java", "Kotlin", "C++"],
+ key="language_select"
+ )
+
+ # Architecture pattern
+ architecture = st.selectbox(
+ "๐๏ธ Architecture Pattern",
+ ["Standard", "MVC", "Microservices", "Serverless", "Clean Architecture", "Hexagonal"],
+ key="architecture_select"
+ )
+
+ # Advanced settings
+ st.markdown("### ๐ฌ Advanced Settings")
+ max_debug_iterations = st.slider("Max Debug Iterations", 1, 10, 3, key="debug_iter")
+ auto_test = st.checkbox("Auto-run tests", value=True, key="auto_test")
+ auto_debug = st.checkbox("Auto-debug failures", value=True, key="auto_debug")
+
+ return language, architecture, max_debug_iterations, auto_test, auto_debug
+
+def render_main_content():
+ st.markdown('โพ๏ธ Singularity-AI
', unsafe_allow_html=True)
+ st.markdown('Where AI meets infinity โพ๏ธ
', unsafe_allow_html=True)
+
+ tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
+ "๐ Generate", "๐ง Build & Test", "๐ Analysis", "๐ Dashboard", "๐ก๏ธ Security", "๐ Deploy"
+ ])
+
+ return tab1, tab2, tab3, tab4, tab5, tab6
+
+def render_generate_tab(language, architecture):
+ with st.expander("๐ Project Generator", expanded=True):
+ col1, col2 = st.columns([3, 1])
+
+ with col1:
+ prompt = st.text_area(
+ "๐ Describe your project:",
+ placeholder="Build a REST API for a todo app with user authentication, SQLite database, and CRUD operations",
+ height=120,
+ key="project_prompt"
+ )
+
+ with col2:
+ template = st.selectbox(
+ "โก Quick Templates",
+ ["Custom", "Web App + Auth", "REST API", "ML Service", "CLI Tool", "Microservice"],
+ key="template_select"
+ )
+
+ template_prompts = {
+ "Custom": "",
+ "Web App + Auth": "Create a modern web application with user authentication, responsive design, and database integration",
+ "REST API": "Build a RESTful API with CRUD operations, authentication, and comprehensive documentation",
+ "ML Service": "Create a machine learning inference service with model loading, prediction endpoints, and monitoring",
+ "CLI Tool": "Build a command-line tool with argument parsing, configuration management, and user-friendly output",
+ "Microservice": "Create a microservice with health checks, logging, metrics, and containerization"
+ }
+
+ default_prompt = template_prompts.get(template, "")
+
+ if st.button("๐งโโ๏ธ Generate Project", type="primary", key="generate_btn"):
+ if prompt:
+ return prompt
+ else:
+ st.error("โ ๏ธ Please provide a project description")
+ return None
+
+def render_project_overview(language, architecture):
+ if st.session_state.current_project and st.session_state.generation_status == "success":
+ project = st.session_state.current_project
+
+ st.markdown('โจ Project generated successfully!
', unsafe_allow_html=True)
+
+ st.markdown("### ๐ Project Overview")
+ col1, col2 = st.columns(2)
+
+ with col1:
+ st.markdown(f"**๐ท๏ธ Name:** `{project['project_name']}`")
+ st.markdown(f"**๐ป Language:** `{language}`")
+ st.markdown(f"**๐ Files:** `{st.session_state.project_metrics['total_files']}`")
+
+ with col2:
+ st.markdown(f"**๐ฆ Dependencies:** `{st.session_state.project_metrics['dependencies']}`")
+ st.markdown(f"**๐๏ธ Architecture:** `{architecture}`")
+ st.markdown(f"**๐ Lines:** `{st.session_state.project_metrics['total_lines']}`")
+
+ st.markdown(f"**๐ Description:** {project['description']}")
+
+ st.markdown("### ๐ Generated Files")
+ selected_file = st.selectbox(
+ "View file:",
+ list(project['files'].keys()),
+ key="file_browser"
+ )
+
+ if selected_file:
+ file_ext = selected_file.split('.')[-1] if '.' in selected_file else 'text'
+ st.code(project['files'][selected_file], language=file_ext)
+
+ zip_data = create_zip_download(project)
+ st.download_button(
+ label="๐ฆ Download Project ZIP",
+ data=zip_data,
+ file_name=f"{project['project_name']}.zip",
+ mime="application/zip",
+ key="download_zip"
+ )
+
+def render_build_test_tab(language, max_debug_iterations):
+ if not st.session_state.current_project:
+ st.markdown('โน๏ธ Generate a project first to see build and test options
', unsafe_allow_html=True)
+ return
+
+ project = st.session_state.current_project
+
+ col1, col2, col3 = st.columns(3)
+
+ with col1:
+ if st.button("๐จ Build Project", key="build_btn"):
+ return "build"
+
+ if st.session_state.build_output:
+ if st.session_state.build_output["success"]:
+ st.markdown('โ
Build successful!
', unsafe_allow_html=True)
+ else:
+ st.markdown('โ Build failed
', unsafe_allow_html=True)
+
+ st.code(st.session_state.build_output["output"], language="bash")
+
+ with col2:
+ if st.button("๐งช Run Tests", key="test_btn"):
+ return "test"
+
+ if st.session_state.test_results:
+ if st.session_state.test_results["success"]:
+ st.markdown('โ
All tests passed!
', unsafe_allow_html=True)
+ else:
+ st.markdown('โ Some tests failed
', unsafe_allow_html=True)
+
+ st.code(st.session_state.test_results["output"], language="bash")
+
+ if st.session_state.test_results["errors"]:
+ st.error("Test Errors:")
+ st.code(st.session_state.test_results["errors"], language="bash")
+
+ with col3:
+ if st.button("๐ง Auto-Debug", key="debug_btn"):
+ if st.session_state.test_results and not st.session_state.test_results["success"]:
+ return "debug"
+ else:
+ st.info("No failing tests to debug")
+
+ st.markdown("### ๐ Refactoring Options")
+ refactor_col1, refactor_col2, refactor_col3, refactor_col4 = st.columns(4)
+
+ with refactor_col1:
+ if st.button("๐ Readability", key="refactor_readability"):
+ return "refactor_readability"
+
+ if "readability" in st.session_state.refactor_results:
+ with st.expander("๐ Readability Refactor Result"):
+ st.markdown(st.session_state.refactor_results["readability"])
+
+ with refactor_col2:
+ if st.button("โก Performance", key="refactor_performance"):
+ return "refactor_performance"
+
+ if "performance" in st.session_state.refactor_results:
+ with st.expander("โก Performance Refactor Result"):
+ st.markdown(st.session_state.refactor_results["performance"])
+
+ with refactor_col3:
+ if st.button("๐ฆ Size", key="refactor_size"):
+ return "refactor_size"
+
+ if "size" in st.session_state.refactor_results:
+ with st.expander("๐ฆ Size Refactor Result"):
+ st.markdown(st.session_state.refactor_results["size"])
+
+ with refactor_col4:
+ if st.button("๐ก๏ธ Security", key="refactor_security"):
+ return "refactor_security"
+
+ if "security" in st.session_state.refactor_results:
+ with st.expander("๐ก๏ธ Security Refactor Result"):
+ st.markdown(st.session_state.refactor_results["security"])
+
+def render_analysis_tab(language):
+ if not st.session_state.current_project:
+ st.markdown('โน๏ธ Generate a project first to see analysis options
', unsafe_allow_html=True)
+ return
+
+ project = st.session_state.current_project
+
+ st.markdown("### ๐ Explain Code")
+ explain_file = st.selectbox(
+ "Select file to explain:",
+ list(project['files'].keys()),
+ key="explain_file_select"
+ )
+
+ if st.button("๐ Explain This File", key="explain_btn"):
+ with st.spinner("๐ง Analyzing code..."):
+ explanation = st.session_state.oracle.explain_code(
+ project['files'][explain_file],
+ language
+ )
+ st.session_state.explanations[explain_file] = explanation
+
+ if explain_file in st.session_state.explanations:
+ with st.expander(f"๐ Explanation: {explain_file}"):
+ st.markdown(st.session_state.explanations[explain_file])
+
+ st.markdown("### ๐๏ธ Architecture Overview")
+
+ if st.button("๐ Visualize Architecture", key="viz_arch_btn"):
+ files = list(project['files'].keys())
+ file_types = {}
+
+ for file in files:
+ ext = file.split('.')[-1] if '.' in file else 'other'
+ file_types[ext] = file_types.get(ext, 0) + 1
+
+ st.session_state.arch_viz_data = file_types
+
+ if hasattr(st.session_state, 'arch_viz_data'):
+ fig = px.pie(
+ values=list(st.session_state.arch_viz_data.values()),
+ names=list(st.session_state.arch_viz_data.keys()),
+ title="Project File Distribution",
+ color_discrete_sequence=px.colors.qualitative.Set3
+ )
+ fig.update_layout(
+ plot_bgcolor='rgba(0,0,0,0)',
+ paper_bgcolor='rgba(0,0,0,0)',
+ font_color='white'
+ )
+ st.plotly_chart(fig, use_container_width=True)
+
+ st.markdown("### ๐ฆ Dependencies")
+ deps = project.get('dependencies', [])
+ if deps:
+ dep_df = pd.DataFrame({'Dependency': deps, 'Type': ['External'] * len(deps)})
+ st.dataframe(dep_df, use_container_width=True)
+ else:
+ st.info("No external dependencies found")
+
+ st.markdown("### ๐ Code Metrics")
+
+ if hasattr(st.session_state, 'project_metrics') and st.session_state.project_metrics:
+ metrics = st.session_state.project_metrics
+ col1, col2, col3, col4 = st.columns(4)
+ col1.metric("Total Files", metrics['total_files'])
+ col2.metric("Total Lines", metrics['total_lines'])
+ col3.metric("Avg Lines/File", metrics['avg_lines_per_file'])
+ col4.metric("Dependencies", metrics['dependencies'])
+ elif st.session_state.current_project:
+ project = st.session_state.current_project
+ total_files = len(project['files'])
+ total_lines = sum(len(content.split('\n')) for content in project['files'].values())
+ avg_lines = round(total_lines/total_files) if total_files > 0 else 0
+ dependencies = len(project.get('dependencies', []))
+
+ col1, col2, col3, col4 = st.columns(4)
+ col1.metric("Total Files", total_files)
+ col2.metric("Total Lines", total_lines)
+ col3.metric("Avg Lines/File", avg_lines)
+ col4.metric("Dependencies", dependencies)
+
+def render_dashboard_tab():
+ if not st.session_state.current_project:
+ st.markdown('โน๏ธ Generate a project first to see the dashboard
', unsafe_allow_html=True)
+ return
+
+ health_score = 85
+ col1, col2, col3 = st.columns(3)
+
+ with col1:
+ st.metric("๐ฅ Health Score", f"{health_score}%", "5%")
+ with col2:
+ test_coverage = "78%" if st.session_state.test_results and st.session_state.test_results["success"] else "0%"
+ st.metric("๐งช Test Coverage", test_coverage, "12%")
+ with col3:
+ security_rating = "A-" if "security" in st.session_state.refactor_results else "C"
+ st.metric("๐ก๏ธ Security Rating", security_rating, "0")
+
+ st.markdown("### ๐ Project Timeline")
+ timeline_events = []
+ if st.session_state.current_project:
+ timeline_events.append(('Generated', datetime.now().strftime('%H:%M:%S'), 'โ
'))
+ if st.session_state.build_output:
+ status = 'โ
' if st.session_state.build_output["success"] else 'โ'
+ timeline_events.append(('Built', datetime.now().strftime('%H:%M:%S'), status))
+ if st.session_state.test_results:
+ status = 'โ
' if st.session_state.test_results["success"] else 'โ'
+ timeline_events.append(('Tested', datetime.now().strftime('%H:%M:%S'), status))
+ if st.session_state.security_report:
+ timeline_events.append(('Secured', datetime.now().strftime('%H:%M:%S'), 'โ
'))
+
+ if timeline_events:
+ timeline_data = pd.DataFrame(timeline_events, columns=['Event', 'Timestamp', 'Status'])
+ st.dataframe(timeline_data, use_container_width=True)
+
+ st.markdown("### ๐ Quality Trends")
+
+ dates = pd.date_range(start='2024-01-01', end='2024-12-31', freq='M')
+ quality_data = pd.DataFrame({
+ 'Date': dates,
+ 'Code Quality': [75 + i*2 + (i%3)*5 for i in range(len(dates))],
+ 'Test Coverage': [60 + i*1.5 + (i%2)*3 for i in range(len(dates))],
+ 'Security Score': [70 + i*1.8 + (i%4)*4 for i in range(len(dates))]
+ })
+
+ fig = px.line(
+ quality_data,
+ x='Date',
+ y=['Code Quality', 'Test Coverage', 'Security Score'],
+ title="Project Health Over Time"
+ )
+ fig.update_layout(
+ plot_bgcolor='rgba(0,0,0,0)',
+ paper_bgcolor='rgba(0,0,0,0)',
+ font_color='white'
+ )
+ st.plotly_chart(fig, use_container_width=True)
+
+def render_security_tab(language):
+ if not st.session_state.current_project:
+ st.markdown('โน๏ธ Generate a project first to run security analysis
', unsafe_allow_html=True)
+ return
+
+ if st.button("๐ Run Security Scan", key="security_scan_btn"):
+ return "scan"
+
+ if st.session_state.security_report:
+ if st.session_state.security_report["success"]:
+ st.markdown("### ๐ก๏ธ Security Report")
+ st.markdown(st.session_state.security_report["report"])
+ else:
+ st.error(f"Security scan failed: {st.session_state.security_report['error']}")
+
+ st.markdown("### โ
Security Checklist")
+
+ security_items = [
+ "Input validation implemented",
+ "Authentication mechanisms in place",
+ "Authorization checks present",
+ "SQL injection prevention",
+ "XSS protection enabled",
+ "CSRF tokens implemented",
+ "Secure headers configured",
+ "Dependency vulnerabilities checked"
+ ]
+
+ for i, item in enumerate(security_items):
+ st.checkbox(item, value=False, key=f"security_check_{i}")
+
+def render_deploy_tab(language):
+ if not st.session_state.current_project:
+ st.markdown('โน๏ธ Generate a project first to see deployment options
', unsafe_allow_html=True)
+ return
+
+ project = st.session_state.current_project
+
+ col1, col2 = st.columns(2)
+
+ with col1:
+ st.markdown("### ๐ CI/CD Configuration")
+ cicd_platform = st.selectbox(
+ "Platform:",
+ ["GitHub Actions", "GitLab CI", "CircleCI", "Jenkins"],
+ key="cicd_platform_select"
+ )
+
+ if st.button("Generate CI/CD Config", key="generate_cicd_btn"):
+ with st.spinner("โ๏ธ Generating CI/CD configuration..."):
+ cicd_config = st.session_state.oracle.generate_cicd(
+ project, language, cicd_platform
+ )
+ st.session_state.cicd_configs[cicd_platform] = cicd_config
+
+ if cicd_platform in st.session_state.cicd_configs:
+ st.code(st.session_state.cicd_configs[cicd_platform], language="yaml")
+
+ st.download_button(
+ label="๐ฅ Download CI/CD Config",
+ data=st.session_state.cicd_configs[cicd_platform],
+ file_name=f"{cicd_platform.lower().replace(' ', '_')}.yml",
+ mime="text/yaml",
+ key=f"download_cicd_{cicd_platform}"
+ )
+
+ with col2:
+ st.markdown("### ๐ณ Containerization")
+
+ if st.button("Generate Dockerfile", key="generate_dockerfile_btn"):
+ dockerfile_prompt = f"""
+ Generate a production-ready Dockerfile for this {language} project:
+
+ Project: {project['project_name']}
+ Dependencies: {project.get('dependencies', [])}
+ Build Commands: {project.get('build_commands', [])}
+ Run Commands: {project.get('run_commands', [])}
+
+ Include:
+ - Multi-stage build
+ - Security best practices
+ - Optimized layer caching
+ - Non-root user
+ - Health checks
+ """
+
+ with st.spinner("๐ณ Generating Dockerfile..."):
+ try:
+ response = st.session_state.oracle.model.generate_content(dockerfile_prompt)
+ st.session_state.dockerfile_content = response.text
+ except Exception as e:
+ st.error(f"Dockerfile generation failed: {str(e)}")
+
+ if hasattr(st.session_state, 'dockerfile_content'):
+ st.code(st.session_state.dockerfile_content, language="dockerfile")
+
+ st.download_button(
+ label="๐ฅ Download Dockerfile",
+ data=st.session_state.dockerfile_content,
+ file_name="Dockerfile",
+ mime="text/plain",
+ key="download_dockerfile"
+ )
+
+ st.markdown("### ๐ Deployment Scripts")
+
+ deployment_type = st.selectbox(
+ "Deployment Target:",
+ ["Docker Compose", "Kubernetes", "AWS ECS", "Google Cloud Run", "Azure Container Apps"],
+ key="deployment_type_select"
+ )
+
+ if st.button("Generate Deployment Script", key="generate_deploy_btn"):
+ deploy_prompt = f"""
+ Generate deployment configuration for {deployment_type} for this project:
+
+ Project: {project['project_name']}
+ Language: {language}
+ Dependencies: {project.get('dependencies', [])}
+ Build Commands: {project.get('build_commands', [])}
+ Run Commands: {project.get('run_commands', [])}
+
+ Include:
+ - Service definitions
+ - Environment variables
+ - Resource limits
+ - Health checks
+ - Networking configuration
+ - Scaling policies
+ - Monitoring setup
+ """
+
+ with st.spinner(f"๐ Generating {deployment_type} configuration..."):
+ try:
+ response = st.session_state.oracle.model.generate_content(deploy_prompt)
+ if 'deploy_configs' not in st.session_state:
+ st.session_state.deploy_configs = {}
+ st.session_state.deploy_configs[deployment_type] = response.text
+ except Exception as e:
+ st.error(f"Deployment configuration generation failed: {str(e)}")
+
+ if hasattr(st.session_state, 'deploy_configs') and deployment_type in st.session_state.deploy_configs:
+ st.code(st.session_state.deploy_configs[deployment_type], language="yaml")
+
+ file_extensions = {
+ "Docker Compose": "docker-compose.yml",
+ "Kubernetes": "k8s-deployment.yaml",
+ "AWS ECS": "ecs-task-definition.json",
+ "Google Cloud Run": "cloudrun-service.yaml",
+ "Azure Container Apps": "containerapp.yaml"
+ }
+
+ filename = file_extensions.get(deployment_type, "deployment.yaml")
+
+ st.download_button(
+ label=f"๐ฅ Download {deployment_type} Config",
+ data=st.session_state.deploy_configs[deployment_type],
+ file_name=filename,
+ mime="text/yaml",
+ key=f"download_deploy_{deployment_type}"
+ )
+
+ st.markdown("### ๐ง Environment Configuration")
+
+ env_type = st.selectbox(
+ "Environment Type:",
+ ["Development", "Staging", "Production"],
+ key="env_type_select"
+ )
+
+ if st.button("Generate Environment Config", key="generate_env_btn"):
+ env_prompt = f"""
+ Generate environment configuration for {env_type} environment:
+
+ Project: {project['project_name']}
+ Language: {language}
+
+ Include appropriate settings for {env_type}:
+ - Environment variables
+ - Database configurations
+ - Logging levels
+ - Security settings
+ - Performance optimizations
+ - Monitoring configurations
+ """
+
+ with st.spinner(f"โ๏ธ Generating {env_type} environment config..."):
+ try:
+ response = st.session_state.oracle.model.generate_content(env_prompt)
+ if 'env_configs' not in st.session_state:
+ st.session_state.env_configs = {}
+ st.session_state.env_configs[env_type] = response.text
+ except Exception as e:
+ st.error(f"Environment configuration generation failed: {str(e)}")
+
+ if hasattr(st.session_state, 'env_configs') and env_type in st.session_state.env_configs:
+ st.code(st.session_state.env_configs[env_type], language="bash")
+
+ st.download_button(
+ label=f"๐ฅ Download {env_type} Config",
+ data=st.session_state.env_configs[env_type],
+ file_name=f".env.{env_type.lower()}",
+ mime="text/plain",
+ key=f"download_env_{env_type}"
+ )
+
+def render_footer():
+ st.markdown("---")
+ st.markdown(
+ """
+
+
โพ๏ธ Singularity-AI - Where AI meets infinity
+
Autonomous Software Engineering Assistant
+
Powered by Google Gemini โข Built with Streamlit โข Enhanced with infinite possibilities
+
โพ๏ธ
+
+ """,
+ unsafe_allow_html=True
+ )
diff --git a/src/utils.py b/src/utils.py
new file mode 100644
index 0000000..4153e3b
--- /dev/null
+++ b/src/utils.py
@@ -0,0 +1,39 @@
+import os
+import tempfile
+import zipfile
+import streamlit as st
+from typing import Dict
+
+def create_project_files(project_data: Dict, base_path: str):
+ """Create actual files from project data"""
+ # Ensure base directory exists
+ os.makedirs(base_path, exist_ok=True)
+
+ for filename, content in project_data["files"].items():
+ file_path = os.path.join(base_path, filename)
+
+ # Create directory if filename contains subdirectories
+ file_dir = os.path.dirname(file_path)
+ if file_dir and file_dir != base_path:
+ os.makedirs(file_dir, exist_ok=True)
+
+ try:
+ with open(file_path, 'w', encoding='utf-8') as f:
+ f.write(content)
+ except Exception as e:
+ st.error(f"Failed to create file {filename}: {str(e)}")
+ continue
+
+def create_zip_download(project_data: Dict) -> bytes:
+ """Create downloadable zip file"""
+ zip_buffer = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
+
+ with zipfile.ZipFile(zip_buffer.name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
+ for filename, content in project_data["files"].items():
+ zip_file.writestr(filename, content)
+
+ with open(zip_buffer.name, 'rb') as f:
+ zip_data = f.read()
+
+ os.unlink(zip_buffer.name)
+ return zip_data