codeguardian-offline 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. codeguardian_offline-0.1.0/PKG-INFO +155 -0
  2. codeguardian_offline-0.1.0/README.md +117 -0
  3. codeguardian_offline-0.1.0/codeguardian/__init__.py +1 -0
  4. codeguardian_offline-0.1.0/codeguardian/ai/__init__.py +1 -0
  5. codeguardian_offline-0.1.0/codeguardian/ai/health.py +62 -0
  6. codeguardian_offline-0.1.0/codeguardian/ai/ollama_client.py +26 -0
  7. codeguardian_offline-0.1.0/codeguardian/ai/rag.py +68 -0
  8. codeguardian_offline-0.1.0/codeguardian/ai/test_generator.py +51 -0
  9. codeguardian_offline-0.1.0/codeguardian/cli/__init__.py +1 -0
  10. codeguardian_offline-0.1.0/codeguardian/cli/ask.py +83 -0
  11. codeguardian_offline-0.1.0/codeguardian/cli/ci.py +47 -0
  12. codeguardian_offline-0.1.0/codeguardian/cli/generate.py +20 -0
  13. codeguardian_offline-0.1.0/codeguardian/cli/init.py +68 -0
  14. codeguardian_offline-0.1.0/codeguardian/cli/report.py +42 -0
  15. codeguardian_offline-0.1.0/codeguardian/cli/scan.py +39 -0
  16. codeguardian_offline-0.1.0/codeguardian/cli/serve.py +23 -0
  17. codeguardian_offline-0.1.0/codeguardian/cli/test.py +93 -0
  18. codeguardian_offline-0.1.0/codeguardian/core/__init__.py +1 -0
  19. codeguardian_offline-0.1.0/codeguardian/core/chroma_compat.py +26 -0
  20. codeguardian_offline-0.1.0/codeguardian/core/config_loader.py +41 -0
  21. codeguardian_offline-0.1.0/codeguardian/core/config_models.py +79 -0
  22. codeguardian_offline-0.1.0/codeguardian/core/db.py +90 -0
  23. codeguardian_offline-0.1.0/codeguardian/core/extras.py +20 -0
  24. codeguardian_offline-0.1.0/codeguardian/core/logger.py +16 -0
  25. codeguardian_offline-0.1.0/codeguardian/main.py +21 -0
  26. codeguardian_offline-0.1.0/codeguardian/reports/__init__.py +1 -0
  27. codeguardian_offline-0.1.0/codeguardian/reports/generator.py +78 -0
  28. codeguardian_offline-0.1.0/codeguardian/reports/junit.py +56 -0
  29. codeguardian_offline-0.1.0/codeguardian/scanner/__init__.py +1 -0
  30. codeguardian_offline-0.1.0/codeguardian/scanner/grammars.py +71 -0
  31. codeguardian_offline-0.1.0/codeguardian/scanner/ruff_runner.py +34 -0
  32. codeguardian_offline-0.1.0/codeguardian/scanner/semgrep_runner.py +36 -0
  33. codeguardian_offline-0.1.0/codeguardian/scanner/tree_sitter_runner.py +80 -0
  34. codeguardian_offline-0.1.0/codeguardian/testers/__init__.py +1 -0
  35. codeguardian_offline-0.1.0/codeguardian/testers/api.py +81 -0
  36. codeguardian_offline-0.1.0/codeguardian/testers/ui.py +82 -0
  37. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/PKG-INFO +155 -0
  38. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/SOURCES.txt +42 -0
  39. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/dependency_links.txt +1 -0
  40. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/entry_points.txt +2 -0
  41. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/requires.txt +31 -0
  42. codeguardian_offline-0.1.0/codeguardian_offline.egg-info/top_level.txt +1 -0
  43. codeguardian_offline-0.1.0/pyproject.toml +74 -0
  44. codeguardian_offline-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: codeguardian-offline
3
+ Version: 0.1.0
4
+ Summary: Offline AI QA Assistant
5
+ Author-email: CodeGuardian Maintainers <maintainers@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Software Development :: Quality Assurance
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: typer>=0.12.0
14
+ Requires-Dist: rich>=13.0.0
15
+ Requires-Dist: sqlmodel>=0.0.16
16
+ Requires-Dist: httpx>=0.27.0
17
+ Provides-Extra: ui
18
+ Requires-Dist: playwright>=1.42.0; extra == "ui"
19
+ Provides-Extra: ai
20
+ Requires-Dist: ollama<1.0,>=0.2.0; extra == "ai"
21
+ Requires-Dist: chromadb<0.6.0,>=0.4.24; extra == "ai"
22
+ Requires-Dist: sentence-transformers>=2.5.1; extra == "ai"
23
+ Provides-Extra: scan
24
+ Requires-Dist: tree-sitter>=0.21.0; extra == "scan"
25
+ Requires-Dist: tree-sitter-python>=0.21.0; extra == "scan"
26
+ Requires-Dist: tree-sitter-javascript>=0.21.0; extra == "scan"
27
+ Requires-Dist: tree-sitter-java>=0.21.0; extra == "scan"
28
+ Provides-Extra: server
29
+ Requires-Dist: fastapi>=0.110.0; extra == "server"
30
+ Requires-Dist: uvicorn>=0.29.0; extra == "server"
31
+ Provides-Extra: full
32
+ Requires-Dist: codeguardian[ai,scan,server,ui]; extra == "full"
33
+ Provides-Extra: dev
34
+ Requires-Dist: codeguardian[full]; extra == "dev"
35
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
36
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
37
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
38
+
39
+ # CodeGuardian
40
+
41
+ An **Offline AI QA Assistant** that tests applications automatically and explains failures.
42
+
43
+ No internet. No API keys. No cloud services.
44
+
45
+ ## Architecture & Features
46
+
47
+ - **CLI Automation**: Built with `Typer` and `Rich` for a premium terminal experience.
48
+ - **API Testing**: Uses `HTTPX` to validate JSON endpoints.
49
+ - **UI Testing**: Uses `Playwright` for headless browser automation and UI validation.
50
+ - **Static Analysis**: Hooks into `Semgrep` and `Ruff`.
51
+ - **RAG & Knowledge Base**: Parses source code with `Tree-sitter`, embeds it using `SentenceTransformers`, and stores it in `ChromaDB`.
52
+ - **Local AI Explanations**: Queries your local `Ollama` (`qwen2.5-coder` recommended) to explain test failures by correlating test errors with the relevant source code.
53
+
54
+ ## Installation
55
+
56
+ Ensure you have Python 3.10+ installed.
57
+
58
+ CodeGuardian uses optional dependencies so you only install what you need.
59
+
60
+ ```bash
61
+ git clone <repository>
62
+ cd CodeGuardian
63
+ python -m venv venv
64
+
65
+ # On Windows:
66
+ .\venv\Scripts\activate
67
+ # On Mac/Linux:
68
+ source venv/bin/activate
69
+ ```
70
+
71
+ Install CodeGuardian with the features you need:
72
+
73
+ | Use case | Command | Approx size |
74
+ |---|---|---|
75
+ | API testing only | `pip install -e .` | ~50MB |
76
+ | + UI testing | `pip install -e .[ui]` | ~200MB |
77
+ | + AI explanations | `pip install -e .[ai]` | ~3GB |
78
+ | + Code scanning | `pip install -e .[scan]` | ~100MB |
79
+ | Everything | `pip install -e .[full]` | ~3.5GB |
80
+
81
+ *(Note: AI explanations require PyTorch which is ~2GB. Playwright requires an extra step: `playwright install chromium`).*
82
+
83
+ ### Install Ollama
84
+
85
+ Install [Ollama](https://ollama.com/) on your local machine if you plan to use AI features. CodeGuardian will automatically pull the recommended model (`qwen2.5-coder`) when you first use the `ask` command.
86
+
87
+ ## Usage
88
+
89
+ ### 1. Initialize
90
+ Initialize the CodeGuardian database and pre-compile any language grammars:
91
+ ```bash
92
+ cd /path/to/your/project
93
+ codeguardian init
94
+ ```
95
+
96
+ ### 2. Configure Tests
97
+ Create a `codeguardian-api.json` or `codeguardian-ui.json` in your project root.
98
+ CodeGuardian will validate your config using Pydantic before running.
99
+
100
+ **codeguardian-api.json**
101
+ ```json
102
+ {
103
+ "base_url": "https://httpbin.org",
104
+ "tests": [
105
+ {"name": "Get Request", "url": "/get", "method": "GET", "expected_status": 200},
106
+ {"name": "Not Found", "url": "/status/404", "method": "GET", "expected_status": 404}
107
+ ]
108
+ }
109
+ ```
110
+
111
+ **codeguardian-ui.json**
112
+ ```json
113
+ {
114
+ "browser": "chromium",
115
+ "headless": true,
116
+ "tests": [
117
+ {
118
+ "name": "Check Example Domain",
119
+ "steps": [
120
+ {"action": "navigate", "url": "http://example.com"},
121
+ {"action": "assert_visible", "selector": "h1"}
122
+ ]
123
+ }
124
+ ]
125
+ }
126
+ ```
127
+
128
+ ### 3. Run Tests
129
+ Run both API and UI tests (results will be logged to SQLite):
130
+ ```bash
131
+ codeguardian test
132
+ # Or target specific suites:
133
+ # codeguardian test --api-only
134
+ # codeguardian test --ui-only
135
+ ```
136
+
137
+ ### 4. Build Knowledge Base
138
+ Scan the project to run static analysis and build the ChromaDB vector index:
139
+ ```bash
140
+ codeguardian scan .
141
+ ```
142
+
143
+ ### 5. Ask the AI
144
+ If tests fail, query the AI. CodeGuardian will fetch the latest failures, pull relevant source code from ChromaDB, and ask Ollama to explain what went wrong:
145
+ ```bash
146
+ codeguardian ask "Why did the API tests fail?"
147
+ ```
148
+
149
+ ### 6. Generate Reports
150
+ Export beautiful HTML reports or JUnit XML for CI/CD integrations:
151
+ ```bash
152
+ codeguardian report --format html
153
+ codeguardian report --format junit
154
+ codeguardian report --format both
155
+ ```
@@ -0,0 +1,117 @@
1
+ # CodeGuardian
2
+
3
+ An **Offline AI QA Assistant** that tests applications automatically and explains failures.
4
+
5
+ No internet. No API keys. No cloud services.
6
+
7
+ ## Architecture & Features
8
+
9
+ - **CLI Automation**: Built with `Typer` and `Rich` for a premium terminal experience.
10
+ - **API Testing**: Uses `HTTPX` to validate JSON endpoints.
11
+ - **UI Testing**: Uses `Playwright` for headless browser automation and UI validation.
12
+ - **Static Analysis**: Hooks into `Semgrep` and `Ruff`.
13
+ - **RAG & Knowledge Base**: Parses source code with `Tree-sitter`, embeds it using `SentenceTransformers`, and stores it in `ChromaDB`.
14
+ - **Local AI Explanations**: Queries your local `Ollama` (`qwen2.5-coder` recommended) to explain test failures by correlating test errors with the relevant source code.
15
+
16
+ ## Installation
17
+
18
+ Ensure you have Python 3.10+ installed.
19
+
20
+ CodeGuardian uses optional dependencies so you only install what you need.
21
+
22
+ ```bash
23
+ git clone <repository>
24
+ cd CodeGuardian
25
+ python -m venv venv
26
+
27
+ # On Windows:
28
+ .\venv\Scripts\activate
29
+ # On Mac/Linux:
30
+ source venv/bin/activate
31
+ ```
32
+
33
+ Install CodeGuardian with the features you need:
34
+
35
+ | Use case | Command | Approx size |
36
+ |---|---|---|
37
+ | API testing only | `pip install -e .` | ~50MB |
38
+ | + UI testing | `pip install -e .[ui]` | ~200MB |
39
+ | + AI explanations | `pip install -e .[ai]` | ~3GB |
40
+ | + Code scanning | `pip install -e .[scan]` | ~100MB |
41
+ | Everything | `pip install -e .[full]` | ~3.5GB |
42
+
43
+ *(Note: AI explanations require PyTorch which is ~2GB. Playwright requires an extra step: `playwright install chromium`).*
44
+
45
+ ### Install Ollama
46
+
47
+ Install [Ollama](https://ollama.com/) on your local machine if you plan to use AI features. CodeGuardian will automatically pull the recommended model (`qwen2.5-coder`) when you first use the `ask` command.
48
+
49
+ ## Usage
50
+
51
+ ### 1. Initialize
52
+ Initialize the CodeGuardian database and pre-compile any language grammars:
53
+ ```bash
54
+ cd /path/to/your/project
55
+ codeguardian init
56
+ ```
57
+
58
+ ### 2. Configure Tests
59
+ Create a `codeguardian-api.json` or `codeguardian-ui.json` in your project root.
60
+ CodeGuardian will validate your config using Pydantic before running.
61
+
62
+ **codeguardian-api.json**
63
+ ```json
64
+ {
65
+ "base_url": "https://httpbin.org",
66
+ "tests": [
67
+ {"name": "Get Request", "url": "/get", "method": "GET", "expected_status": 200},
68
+ {"name": "Not Found", "url": "/status/404", "method": "GET", "expected_status": 404}
69
+ ]
70
+ }
71
+ ```
72
+
73
+ **codeguardian-ui.json**
74
+ ```json
75
+ {
76
+ "browser": "chromium",
77
+ "headless": true,
78
+ "tests": [
79
+ {
80
+ "name": "Check Example Domain",
81
+ "steps": [
82
+ {"action": "navigate", "url": "http://example.com"},
83
+ {"action": "assert_visible", "selector": "h1"}
84
+ ]
85
+ }
86
+ ]
87
+ }
88
+ ```
89
+
90
+ ### 3. Run Tests
91
+ Run both API and UI tests (results will be logged to SQLite):
92
+ ```bash
93
+ codeguardian test
94
+ # Or target specific suites:
95
+ # codeguardian test --api-only
96
+ # codeguardian test --ui-only
97
+ ```
98
+
99
+ ### 4. Build Knowledge Base
100
+ Scan the project to run static analysis and build the ChromaDB vector index:
101
+ ```bash
102
+ codeguardian scan .
103
+ ```
104
+
105
+ ### 5. Ask the AI
106
+ If tests fail, query the AI. CodeGuardian will fetch the latest failures, pull relevant source code from ChromaDB, and ask Ollama to explain what went wrong:
107
+ ```bash
108
+ codeguardian ask "Why did the API tests fail?"
109
+ ```
110
+
111
+ ### 6. Generate Reports
112
+ Export beautiful HTML reports or JUnit XML for CI/CD integrations:
113
+ ```bash
114
+ codeguardian report --format html
115
+ codeguardian report --format junit
116
+ codeguardian report --format both
117
+ ```
@@ -0,0 +1 @@
1
+ """CodeGuardian - Offline AI QA Assistant"""
@@ -0,0 +1 @@
1
+ """AI and RAG module."""
@@ -0,0 +1,62 @@
1
+ # codeguardian/ai/health.py
2
+
3
+ import ollama
4
+ from rich.console import Console
5
+ from rich.progress import Progress, SpinnerColumn, TextColumn
6
+
7
+ console = Console()
8
+
9
+ RECOMMENDED_MODEL = "qwen2.5-coder"
10
+
11
+
12
+ def check_ollama(warn_only: bool = False) -> bool:
13
+ """
14
+ Checks if the Ollama daemon is running.
15
+ If warn_only=True, prints a warning instead of raising.
16
+ Returns True if healthy, False otherwise.
17
+ """
18
+ try:
19
+ ollama.list()
20
+ console.print("[green]✓[/green] Ollama daemon is running")
21
+ return True
22
+ except Exception:
23
+ msg = (
24
+ "[yellow]![/yellow] Ollama is not running.\n"
25
+ " Start it with: [bold]ollama serve[/bold]\n"
26
+ " (Required for [bold]codeguardian ask[/bold])"
27
+ )
28
+ if warn_only:
29
+ console.print(msg)
30
+ return False
31
+ raise RuntimeError(
32
+ "Ollama is not running. Start it with: ollama serve"
33
+ )
34
+
35
+
36
+ def ensure_model(model: str = RECOMMENDED_MODEL):
37
+ """
38
+ Checks if the model is pulled locally. Pulls it if not.
39
+ """
40
+ check_ollama()
41
+
42
+ available = {m["name"] for m in ollama.list().get("models", [])}
43
+
44
+ if model in available:
45
+ console.print(f"[green]✓[/green] Model [bold]{model}[/bold] is ready")
46
+ return
47
+
48
+ console.print(f"[yellow]Model [bold]{model}[/bold] not found locally. Pulling now...[/yellow]")
49
+ console.print("[dim](This is a one-time download — may take several minutes)[/dim]\n")
50
+
51
+ with Progress(
52
+ SpinnerColumn(),
53
+ TextColumn("[progress.description]{task.description}"),
54
+ console=console,
55
+ ) as progress:
56
+ task = progress.add_task(f"Pulling {model}...", total=None)
57
+ for chunk in ollama.pull(model, stream=True):
58
+ status = chunk.get("status", "")
59
+ if status:
60
+ progress.update(task, description=f"[cyan]{status}[/cyan]")
61
+
62
+ console.print(f"\n[green]✓[/green] Model [bold]{model}[/bold] ready")
@@ -0,0 +1,26 @@
1
+ from codeguardian.core.logger import logger
2
+ from typing import Optional
3
+
4
+ def generate_explanation(prompt: str, model: str = "qwen2.5-coder") -> Optional[str]:
5
+ """
6
+ Sends a prompt to the local Ollama instance and returns the generated explanation.
7
+ """
8
+ from codeguardian.core.extras import require_extra
9
+ require_extra("ollama", "ai")
10
+ import ollama
11
+ try:
12
+ response = ollama.chat(model=model, messages=[
13
+ {
14
+ "role": "system",
15
+ "content": "You are an expert AI QA Engineer. You analyze failed tests and source code to explain failures and suggest fixes."
16
+ },
17
+ {
18
+ "role": "user",
19
+ "content": prompt
20
+ }
21
+ ])
22
+ return response['message']['content']
23
+ except Exception as e:
24
+ logger.error(f"Failed to communicate with local Ollama instance: {e}")
25
+ logger.error("Make sure Ollama is installed and running locally with the model available.")
26
+ return None
@@ -0,0 +1,68 @@
1
+ import os
2
+ from pathlib import Path
3
+ from codeguardian.core.logger import logger
4
+ from typing import List, Dict
5
+
6
+ CODEGUARDIAN_DIR = Path(".codeguardian")
7
+ CHROMA_DB_DIR = CODEGUARDIAN_DIR / "chroma"
8
+
9
+ class CodeRAG:
10
+ def __init__(self):
11
+ from codeguardian.core.extras import require_extra
12
+ require_extra("chromadb", "ai")
13
+ require_extra("sentence_transformers", "ai")
14
+ from codeguardian.core.chroma_compat import get_client, get_or_create_collection
15
+ from sentence_transformers import SentenceTransformer
16
+
17
+ # Ensure directory exists
18
+ CHROMA_DB_DIR.mkdir(parents=True, exist_ok=True)
19
+
20
+ try:
21
+ self.client = get_client(str(CHROMA_DB_DIR))
22
+ self.collection = get_or_create_collection(self.client, "codebase")
23
+ # Load a lightweight embedding model
24
+ self.model = SentenceTransformer('all-MiniLM-L6-v2')
25
+ self.is_ready = True
26
+ except Exception as e:
27
+ logger.error(f"Failed to initialize ChromaDB or SentenceTransformers: {e}")
28
+ self.is_ready = False
29
+
30
+ def add_chunks(self, chunks: List[str], metadatas: List[Dict[str, str]], ids: List[str]):
31
+ if not self.is_ready or not chunks:
32
+ return
33
+
34
+ try:
35
+ embeddings = self.model.encode(chunks).tolist()
36
+ self.collection.add(
37
+ documents=chunks,
38
+ embeddings=embeddings,
39
+ metadatas=metadatas,
40
+ ids=ids
41
+ )
42
+ logger.info(f"Added {len(chunks)} chunks to the vector database.")
43
+ except Exception as e:
44
+ logger.error(f"Failed to add chunks to RAG: {e}")
45
+
46
+ def query(self, query_text: str, n_results: int = 3) -> List[Dict]:
47
+ if not self.is_ready:
48
+ return []
49
+
50
+ try:
51
+ query_embedding = self.model.encode([query_text]).tolist()
52
+ results = self.collection.query(
53
+ query_embeddings=query_embedding,
54
+ n_results=n_results
55
+ )
56
+
57
+ out = []
58
+ if results['documents'] and len(results['documents']) > 0:
59
+ for i in range(len(results['documents'][0])):
60
+ out.append({
61
+ "document": results['documents'][0][i],
62
+ "metadata": results['metadatas'][0][i],
63
+ "distance": results['distances'][0][i]
64
+ })
65
+ return out
66
+ except Exception as e:
67
+ logger.error(f"Failed to query RAG: {e}")
68
+ return []
@@ -0,0 +1,51 @@
1
+ import json
2
+ import os
3
+ from codeguardian.core.logger import logger
4
+ import ollama
5
+
6
+ def generate_api_tests(project_path: str, output_file: str = "codeguardian-api.json"):
7
+ """
8
+ Scans the project to guess endpoints and uses Ollama to generate an API test config.
9
+ """
10
+ logger.info("[bold cyan]Generating API tests using local AI...[/bold cyan]")
11
+
12
+ # We will simply ask Ollama to generate a config based on a standard template.
13
+ # In a real scenario, this would first use Tree-sitter to find all endpoints.
14
+ prompt = """
15
+ You are an expert QA Engineer.
16
+ I have a local FastAPI server running on http://127.0.0.1:8000.
17
+ It has the following endpoints:
18
+ 1. GET /
19
+ 2. GET /users
20
+ 3. POST /users (requires JSON body with 'name')
21
+ 4. GET /error
22
+
23
+ Generate a complete JSON configuration for my testing tool.
24
+ The JSON must have a 'base_url' and a list of 'endpoints'.
25
+ Each endpoint object must have 'path', 'method', and 'expected_status'.
26
+ Return ONLY the raw JSON without any markdown formatting or backticks.
27
+ """
28
+ try:
29
+ response = ollama.chat(model='qwen2.5-coder', messages=[{"role": "user", "content": prompt}])
30
+ raw_json = response['message']['content'].strip()
31
+
32
+ # Strip potential markdown formatting if the model still includes it
33
+ if raw_json.startswith("```json"):
34
+ raw_json = raw_json[7:]
35
+ if raw_json.startswith("```"):
36
+ raw_json = raw_json[3:]
37
+ if raw_json.endswith("```"):
38
+ raw_json = raw_json[:-3]
39
+
40
+ config = json.loads(raw_json)
41
+
42
+ out_path = os.path.join(project_path, output_file)
43
+ with open(out_path, "w") as f:
44
+ json.dump(config, f, indent=2)
45
+
46
+ logger.info(f"[bold green]Successfully generated {output_file}[/bold green]")
47
+ except json.JSONDecodeError:
48
+ logger.error("[bold red]Failed to parse AI output as JSON.[/bold red]")
49
+ logger.debug(raw_json)
50
+ except Exception as e:
51
+ logger.error(f"[bold red]Failed to generate tests: {e}[/bold red]")
@@ -0,0 +1 @@
1
+ """CLI modules."""
@@ -0,0 +1,83 @@
1
+ import typer
2
+ from rich.console import Console
3
+ from codeguardian.core.logger import logger
4
+ from codeguardian.core.db import get_session, TestResult, is_scanned, get_scan_summary, get_engine
5
+ from codeguardian.ai.rag import CodeRAG
6
+ from codeguardian.ai.ollama_client import generate_explanation
7
+ from sqlmodel import select
8
+ from codeguardian.ai.health import check_ollama, ensure_model, RECOMMENDED_MODEL
9
+
10
+ console = Console()
11
+ app = typer.Typer(help="Ask the local AI about failures.")
12
+
13
+ @app.callback(invoke_without_command=True)
14
+ def ask(query: str = typer.Argument(..., help="Question to ask the AI")):
15
+ """
16
+ Queries the local Ollama LLM with context from the vector DB and recent test results.
17
+ """
18
+ engine = get_engine()
19
+
20
+ # Guard: knowledge base must exist
21
+ if not is_scanned(engine):
22
+ console.print(
23
+ "\n[bold red]No knowledge base found.[/bold red]\n"
24
+ "The AI needs your codebase indexed before it can explain failures.\n\n"
25
+ "Run first: [bold]codeguardian scan .[/bold]\n"
26
+ )
27
+ raise typer.Exit(1)
28
+
29
+ summary = get_scan_summary(engine)
30
+ console.print(
31
+ f"[dim]Knowledge base: {summary.file_count} files, "
32
+ f"{summary.chunk_count} chunks "
33
+ f"(last scanned: {summary.scanned_at.strftime('%Y-%m-%d %H:%M')})[/dim]\n"
34
+ )
35
+
36
+ check_ollama()
37
+ ensure_model()
38
+
39
+ logger.info(f"[bold magenta]Querying AI with:[/bold magenta] {query}")
40
+
41
+ # 1. Fetch recent failed tests from SQLite
42
+ session = next(get_session())
43
+ failed_tests = session.exec(
44
+ select(TestResult).where(TestResult.status == "FAIL").order_by(TestResult.id.desc()).limit(5)
45
+ ).all()
46
+
47
+ test_context = "Recent Failed Tests:\n"
48
+ if not failed_tests:
49
+ test_context += "None found.\n"
50
+ for t in failed_tests:
51
+ test_context += f"- {t.endpoint_or_element}: {t.error_message}\n"
52
+
53
+ # 2. Fetch relevant code from RAG
54
+ rag = CodeRAG()
55
+ rag_results = rag.query(query, n_results=3)
56
+ code_context = "Relevant Code Snippets:\n"
57
+
58
+ if not rag_results:
59
+ code_context += "None found.\n"
60
+ for r in rag_results:
61
+ meta = r.get("metadata", {})
62
+ code = r.get("document", "")
63
+ code_context += f"--- {meta.get('file', 'Unknown File')} ({meta.get('name', '')}) ---\n"
64
+ code_context += f"{code}\n\n"
65
+
66
+ # 3. Construct prompt
67
+ prompt = f"""
68
+ User Query: {query}
69
+
70
+ {test_context}
71
+
72
+ {code_context}
73
+
74
+ Based on the above context, explain the failure and suggest a fix.
75
+ """
76
+ logger.info("[bold]Generating explanation (this may take a moment)...[/bold]")
77
+ explanation = generate_explanation(prompt)
78
+
79
+ if explanation:
80
+ logger.info("\n[bold green]AI Explanation:[/bold green]")
81
+ logger.info(explanation)
82
+ else:
83
+ logger.error("Could not generate explanation.")
@@ -0,0 +1,47 @@
1
+ import typer
2
+ import os
3
+ from codeguardian.core.logger import logger
4
+
5
+ app = typer.Typer(help="CI/CD Integration.")
6
+
7
+ @app.callback(invoke_without_command=True)
8
+ def ci(
9
+ platform: str = typer.Option("github", help="CI platform (github, gitlab)")
10
+ ):
11
+ """
12
+ Generates a template workflow for your CI/CD pipeline.
13
+ """
14
+ logger.info(f"[bold cyan]Generating CI template for {platform}...[/bold cyan]")
15
+
16
+ if platform.lower() == "github":
17
+ template = """name: CodeGuardian QA
18
+ on: [push, pull_request]
19
+
20
+ jobs:
21
+ qa:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v3
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v4
27
+ with:
28
+ python-version: "3.10"
29
+ - name: Install Dependencies
30
+ run: |
31
+ pip install -r requirements.txt
32
+ pip install codeguardian
33
+ - name: Run App
34
+ run: |
35
+ # Start your app in the background here
36
+ # e.g., uvicorn main:app --port 8000 &
37
+ - name: Run CodeGuardian
38
+ run: |
39
+ codeguardian init
40
+ codeguardian test --fail-on-error
41
+ """
42
+ os.makedirs(".github/workflows", exist_ok=True)
43
+ with open(".github/workflows/codeguardian.yml", "w") as f:
44
+ f.write(template)
45
+ logger.info("[bold green]Created .github/workflows/codeguardian.yml[/bold green]")
46
+ else:
47
+ logger.warning(f"Platform {platform} is not fully supported yet.")
@@ -0,0 +1,20 @@
1
+ import typer
2
+ from codeguardian.core.logger import logger
3
+ from codeguardian.ai.test_generator import generate_api_tests
4
+
5
+ app = typer.Typer(help="Generate tests automatically using AI.")
6
+
7
+ @app.callback(invoke_without_command=True)
8
+ def generate(
9
+ project_path: str = typer.Argument(".", help="Path to the project"),
10
+ type: str = typer.Option("api", help="Type of tests to generate (api or ui)")
11
+ ):
12
+ """
13
+ Scans the project and generates tests using Ollama.
14
+ """
15
+ logger.info(f"[bold yellow]Generating {type} tests for {project_path}[/bold yellow]")
16
+
17
+ if type.lower() == "api":
18
+ generate_api_tests(project_path)
19
+ else:
20
+ logger.warning(f"Generation for type '{type}' is not yet implemented.")