AbdulElahGwaith commited on
Commit
6d82353
·
verified ·
1 Parent(s): 3f74de1

Upload folder using huggingface_hub

Browse files
README.md ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GitHub Auto-Guardian
2
+
3
+ ## Overview
4
+
5
+ GitHub Auto-Guardian is an automated code quality maintenance system for GitHub repositories. It automatically detects and fixes code issues, prevents merging of broken code, and alerts you to problems that require human intervention.
6
+
7
+ ## Features
8
+
9
+ - **Issue Detection**: Analyze code for syntax errors, security vulnerabilities, and code quality issues
10
+ - **Auto-Fix**: Automatically fix formatting issues, linting errors, and style violations
11
+ - **Quality Gate**: Prevent merging of code that doesn't meet quality standards
12
+ - **Smart Alerts**: Notify developers about issues that require human intervention
13
+
14
+ ## Quick Start
15
+
16
+ ### 1. Setup
17
+
18
+ ```bash
19
+ # Copy the .github folder to your project
20
+ cp -r .github/ /path/to/your/project/
21
+
22
+ # Install dependencies
23
+ pip install -r .github/scripts/requirements.txt
24
+ ```
25
+
26
+ ### 2. Configure Branch Protection
27
+
28
+ Go to your GitHub repository settings:
29
+
30
+ 1. Navigate to **Settings** → **Branches** → **Branch protection rules**
31
+ 2. Create a new rule for your main branch
32
+ 3. Enable **Require status checks to pass before merging**
33
+ 4. Add `Auto-Guardian Quality Gate` to the required checks
34
+
35
+ ### 3. Test the System
36
+
37
+ Create a pull request with some code quality issues to see the system in action.
38
+
39
+ ## File Structure
40
+
41
+ ```
42
+ .github/
43
+ ├── workflows/
44
+ │ └── auto-maintenance.yml # Main GitHub Actions workflow
45
+ ├── scripts/
46
+ │ ├── auto-fix.sh # Auto-fix script
47
+ │ ├── code-analyzer.py # Code analysis script
48
+ │ ├── report-generator.py # Report generation script
49
+ │ └── requirements.txt # Python dependencies
50
+ └── configs/
51
+ ├── .eslintrc.json # ESLint configuration
52
+ ├── .prettierrc # Prettier configuration
53
+ └── pyproject.toml # Python tools configuration
54
+ ```
55
+
56
+ ## Local Usage
57
+
58
+ ### Run Code Analysis
59
+
60
+ ```bash
61
+ python .github/scripts/code-analyzer.py
62
+ ```
63
+
64
+ ### Run Auto-Fix
65
+
66
+ ```bash
67
+ bash .github/scripts/auto-fix.sh
68
+ ```
69
+
70
+ ### Generate Report
71
+
72
+ ```bash
73
+ python .github/scripts/report-generator.py --scan-results scan-results.json
74
+ ```
75
+
76
+ ## Supported Languages
77
+
78
+ - Python
79
+ - JavaScript / TypeScript
80
+ - Go
81
+ - Java
82
+
83
+ ## How It Works
84
+
85
+ ### 1. Detection Phase
86
+ The system analyzes your code using multiple tools:
87
+ - Linters (ESLint, Flake8, Pylint)
88
+ - Security scanners (Bandit, custom patterns)
89
+ - Code quality analyzers
90
+
91
+ ### 2. Auto-Fix Phase
92
+ The system automatically fixes issues that are safe to correct:
93
+ - Code formatting
94
+ - Import organization
95
+ - Style violations
96
+ - Deprecated syntax
97
+
98
+ ### 3. Quality Gate Phase
99
+ All changes must pass strict quality checks:
100
+ - Test execution
101
+ - Code complexity limits
102
+ - Type checking
103
+ - Security validation
104
+
105
+ ### 4. Alert Phase
106
+ The system provides clear feedback:
107
+ - Comments on Pull Requests
108
+ - Slack/Discord notifications (optional)
109
+ - Status checks with detailed reports
110
+
111
+ ## Configuration
112
+
113
+ ### Customizing Rules
114
+
115
+ Edit the configuration files to customize behavior:
116
+
117
+ - `.eslintrc.json` - ESLint rules
118
+ - `.prettierrc` - Prettier formatting rules
119
+ - `pyproject.toml` - Python tool settings
120
+ - `.github/workflows/auto-maintenance.yml` - CI/CD pipeline
121
+
122
+ ### Adding New Languages
123
+
124
+ 1. Add language detection to `code-analyzer.py`
125
+ 2. Add fix commands to `auto-fix.sh`
126
+ 3. Create language-specific configurations
127
+
128
+ ## Troubleshooting
129
+
130
+ ### Issues Not Being Fixed
131
+
132
+ 1. Check if the issue is marked as `fixable: false`
133
+ 2. Review the suggestion in the report
134
+ 3. Manual intervention may be required
135
+
136
+ ### False Positives
137
+
138
+ 1. Add suppressions to ESLint/Pylint config
139
+ 2. Use `# noqa` comments in code
140
+ 3. Update the analyzer rules
141
+
142
+ ### Workflow Not Running
143
+
144
+ 1. Verify GitHub Actions are enabled
145
+ 2. Check branch protection settings
146
+ 3. Review workflow syntax
147
+
148
+ ## Contributing
149
+
150
+ 1. Fork the repository
151
+ 2. Create a feature branch
152
+ 3. Make your changes
153
+ 4. Submit a pull request
154
+
155
+ ## License
156
+
157
+ MIT License - feel free to use this in your projects.
158
+
159
+ ## Support
160
+
161
+ For issues and feature requests, please open a GitHub issue.
auto-guardian-system.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:96a306735b7279473a7d16f9f9f8e961e141cab38ed42eb1c747157e6e0964bc
3
+ size 15963
core_system/auto-fix.sh ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # ============================================================================
4
+ # Auto-Guardian: Auto-Fix Script
5
+ # ============================================================================
6
+ # Purpose: Fix common issues automatically without affecting code behavior
7
+ # Supported Languages: JavaScript, Python, TypeScript, Go, Java
8
+ # ============================================================================
9
+
10
+ set -e # Exit on first error
11
+
12
+ # Colors for beautiful output
13
+ RED='\033[0;31m'
14
+ GREEN='\033[0;32m'
15
+ YELLOW='\033[1;33m'
16
+ BLUE='\033[0;34m'
17
+ NC='\033[0m' # No Color
18
+
19
+ # Environment variables
20
+ PROJECT_ROOT=$(git rev-parse --show-toplevel)
21
+ FIXED_COUNT=0
22
+ SKIPPED_COUNT=0
23
+ ERROR_COUNT=0
24
+
25
+ # Helper function for colored logging
26
+ log_info() {
27
+ echo -e "${BLUE}[INFO]${NC} $1"
28
+ }
29
+
30
+ log_success() {
31
+ echo -e "${GREEN}[SUCCESS]${NC} $1"
32
+ ((FIXED_COUNT++))
33
+ }
34
+
35
+ log_warning() {
36
+ echo -e "${YELLOW}[WARNING]${NC} $1"
37
+ ((SKIPPED_COUNT++))
38
+ }
39
+
40
+ log_error() {
41
+ echo -e "${RED}[ERROR]${NC} $1"
42
+ ((ERROR_COUNT++))
43
+ }
44
+
45
+ # ============================================================================
46
+ # Section 1: General File Cleanup
47
+ # ============================================================================
48
+ clean_general() {
49
+ log_info "Starting general file cleanup..."
50
+
51
+ # Remove temporary files
52
+ find . -type f -name "*.pyc" -delete
53
+ find . -type f -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
54
+ find . -type f -name "*.py.bak" -delete
55
+ find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
56
+ find . -type d -name "node_modules" -exec rm -rf {} + 2>/dev/null || true
57
+ find . -type f -name "*.log" -delete 2>/dev/null || true
58
+
59
+ # Clean system files
60
+ find . -type f -name ".DS_Store" -delete
61
+ find . -type f -name "Thumbs.db" -delete
62
+
63
+ log_success "General cleanup completed"
64
+ }
65
+
66
+ # ============================================================================
67
+ # Section 2: Fix JavaScript/TypeScript
68
+ # ============================================================================
69
+ fix_javascript() {
70
+ log_info "Scanning and fixing JavaScript/TypeScript files..."
71
+
72
+ # Check for package.json
73
+ if [ ! -f "package.json" ]; then
74
+ log_warning "No package.json found - skipping JavaScript"
75
+ return
76
+ fi
77
+
78
+ # Install Prettier and ESLint
79
+ if [ -f "package-lock.json" ] || [ -f "yarn.lock" ]; then
80
+ npm ci --prefer-offline --no-audit 2>/dev/null || npm install
81
+ else
82
+ npm install
83
+ fi
84
+
85
+ # Run Prettier for formatting
86
+ if command -v npx &> /dev/null; then
87
+ if [ -f ".prettierrc.js" ] || [ -f ".prettierrc.json" ] || [ -f "prettier.config.js" ]; then
88
+ npx prettier --write "src/**/*.js" "src/**/*.ts" 2>/dev/null || true
89
+ npx prettier --write "**/*.js" "**/*.ts" 2>/dev/null || true
90
+ log_success "JavaScript/TypeScript formatted"
91
+ fi
92
+ fi
93
+
94
+ # Fix ESLint errors
95
+ if command -v npx &> /dev/null && grep -q '"eslint"' package.json; then
96
+ npx eslint --fix "src/**/*.js" "src/**/*.ts" 2>/dev/null || true
97
+ log_success "ESLint errors fixed"
98
+ fi
99
+ }
100
+
101
+ # ============================================================================
102
+ # Section 3: Fix Python
103
+ # ============================================================================
104
+ fix_python() {
105
+ log_info "Scanning and fixing Python files..."
106
+
107
+ # Check for Python files
108
+ if ! find . -name "*.py" -type f | grep -q .; then
109
+ log_warning "No Python files found in project"
110
+ return
111
+ fi
112
+
113
+ # Install formatting tools
114
+ pip install black isort flake8 autoflake 2>/dev/null || true
115
+
116
+ # Remove unused imports with autoflake
117
+ if command -v autoflake &> /dev/null; then
118
+ autoflake --remove-all-unused-imports --recursive --in-place . 2>/dev/null || true
119
+ log_success "Unused imports removed"
120
+ fi
121
+
122
+ # Organize imports with isort
123
+ if command -v isort &> /dev/null; then
124
+ isort --profile black --apply --diff . 2>/dev/null || true
125
+ isort --profile black --apply . 2>/dev/null || true
126
+ log_success "Imports organized"
127
+ fi
128
+
129
+ # Format code with Black
130
+ if command -v black &> /dev/null; then
131
+ black --line-length 100 --target-version py39 --diff . 2>/dev/null || true
132
+ black --line-length 100 --target-version py39 . 2>/dev/null || true
133
+ log_success "Code formatted with Black"
134
+ fi
135
+ }
136
+
137
+ # ============================================================================
138
+ # Section 4: Fix Go
139
+ # ============================================================================
140
+ fix_go() {
141
+ log_info "Scanning and fixing Go files..."
142
+
143
+ # Check for Go files
144
+ if ! find . -name "*.go" -type f | grep -q .; then
145
+ log_warning "No Go files found in project"
146
+ return
147
+ fi
148
+
149
+ # Format code
150
+ if command -v gofmt &> /dev/null; then
151
+ gofmt -w . 2>/dev/null || true
152
+ log_success "Go formatted"
153
+ fi
154
+
155
+ # Fix imports
156
+ if command -v goimports &> /dev/null; then
157
+ goimports -w . 2>/dev/null || true
158
+ log_success "Go imports fixed"
159
+ fi
160
+ }
161
+
162
+ # ============================================================================
163
+ # Section 5: Fix Java
164
+ # ============================================================================
165
+ fix_java() {
166
+ log_info "Scanning and fixing Java files..."
167
+
168
+ # Check for Java files
169
+ if ! find . -name "*.java" -type f | grep -q .; then
170
+ log_warning "No Java files found in project"
171
+ return
172
+ fi
173
+
174
+ # Check for Google Java Format
175
+ if [ -f ".google-java-format" ]; then
176
+ if command -v google-java-format &> /dev/null; then
177
+ google-java-format -i --replace $(find . -name "*.java") 2>/dev/null || true
178
+ log_success "Java formatted"
179
+ fi
180
+ fi
181
+
182
+ # Traditional formatting
183
+ if command -v astyle &> /dev/null; then
184
+ astyle --style=google --recursive "*.java" 2>/dev/null || true
185
+ log_success "Java formatted with Astyle"
186
+ fi
187
+ }
188
+
189
+ # ============================================================================
190
+ # Section 6: Fix YAML/JSON
191
+ # ============================================================================
192
+ fix_config_files() {
193
+ log_info "Scanning and fixing configuration files..."
194
+
195
+ # Install YAML tools
196
+ pip install pyyaml 2>/dev/null || true
197
+
198
+ # Fix YAML
199
+ find . -name "*.yaml" -o -name "*.yml" | while read -r file; do
200
+ if command -v python3 &> /dev/null; then
201
+ python3 -c "
202
+ import yaml
203
+ import sys
204
+ try:
205
+ with open('$file', 'r') as f:
206
+ content = yaml.safe_load(f)
207
+ with open('$file', 'w') as f:
208
+ yaml.dump(content, f, default_flow_style=False, allow_unicode=True)
209
+ print('Fixed: $file')
210
+ except Exception as e:
211
+ pass
212
+ " 2>/dev/null || true
213
+ fi
214
+ done
215
+
216
+ # Format JSON
217
+ find . -name "*.json" | while read -r file; do
218
+ if command -v python3 &> /dev/null; then
219
+ python3 -c "
220
+ import json
221
+ import sys
222
+ try:
223
+ with open('$file', 'r') as f:
224
+ content = json.load(f)
225
+ with open('$file', 'w') as f:
226
+ json.dump(content, f, indent=2, ensure_ascii=False)
227
+ print('Fixed: $file')
228
+ except Exception as e:
229
+ pass
230
+ " 2>/dev/null || true
231
+ fi
232
+ done
233
+
234
+ log_success "Configuration files fixed"
235
+ }
236
+
237
+ # ============================================================================
238
+ # Section 7: Add License Headers
239
+ # ============================================================================
240
+ add_license_headers() {
241
+ log_info "Scanning license headers..."
242
+
243
+ # List of files that need headers
244
+ if [ -f "COPYRIGHT_HEADER.txt" ]; then
245
+ local header=$(cat COPYRIGHT_HEADER.txt)
246
+
247
+ for ext in "*.py" "*.js" "*.ts" "*.java" "*.go"; do
248
+ find . -name "$ext" -type f | while read -r file; do
249
+ # Check for existing header
250
+ if ! head -5 "$file" | grep -q "Copyright"; then
251
+ # Add header
252
+ if [ "$ext" == "*.py" ]; then
253
+ echo "# $header" | cat - "$file" > temp && mv temp "$file"
254
+ elif [ "$ext" == "*.js" ] || [ "$ext" == "*.ts" ]; then
255
+ echo "// $header" | cat - "$file" > temp && mv temp "$file"
256
+ elif [ "$ext" == "*.java" ]; then
257
+ echo "/* $header */" | cat - "$file" > temp && mv temp "$file"
258
+ elif [ "$ext" == "*.go" ]; then
259
+ echo "// $header" | cat - "$file" > temp && mv temp "$file"
260
+ fi
261
+ log_success "License header added: $file"
262
+ fi
263
+ done
264
+ done
265
+ fi
266
+ }
267
+
268
+ # ============================================================================
269
+ # Section 8: Organize Files
270
+ # ============================================================================
271
+ organize_files() {
272
+ log_info "Improving file organization..."
273
+
274
+ # Reorder Python imports
275
+ if [ -f "setup.cfg" ] || [ -f "pyproject.toml" ]; then
276
+ isort --recursive . 2>/dev/null || true
277
+ log_success "Imports reordered"
278
+ fi
279
+
280
+ # Update README.md
281
+ if [ -f "README.md" ]; then
282
+ # Ensure table of contents exists
283
+ if ! grep -q "^## Table of Contents$" README.md && ! grep -q "^## الفهرس$" README.md; then
284
+ echo -e "\n## Table of Contents\n" | cat - README.md > temp && mv temp README.md
285
+ log_success "README.md updated"
286
+ fi
287
+ fi
288
+ }
289
+
290
+ # ============================================================================
291
+ # Section 9: Basic Security Check
292
+ # ============================================================================
293
+ security_check() {
294
+ log_info "Running basic security check..."
295
+
296
+ # Check for passwords or keys in code
297
+ local secrets_patterns=(
298
+ "password\s*=\s*['\"][^'\"]+['\"]"
299
+ "api_key\s*=\s*['\"][^'\"]+['\"]"
300
+ "secret\s*=\s*['\"][^'\"]+['\"]"
301
+ "private_key\s*=\s*['\"][^'\"]+['\"]"
302
+ "AWS_ACCESS_KEY"
303
+ "AWS_SECRET_KEY"
304
+ )
305
+
306
+ for pattern in "${secrets_patterns[@]}"; do
307
+ if grep -rqE "$pattern" . --include="*.py" --include="*.js" --include="*.ts" 2>/dev/null; then
308
+ log_warning "Potential sensitive data found: $pattern"
309
+ fi
310
+ done
311
+
312
+ log_success "Security check completed"
313
+ }
314
+
315
+ # ============================================================================
316
+ # Main Function
317
+ # ============================================================================
318
+ main() {
319
+ echo "=============================================="
320
+ echo " Auto-Guardian: Auto-Fix Script"
321
+ echo "=============================================="
322
+ echo ""
323
+
324
+ cd "$PROJECT_ROOT"
325
+
326
+ # Log start
327
+ echo "Date: $(date)"
328
+ echo "Directory: $PROJECT_ROOT"
329
+ echo ""
330
+
331
+ # Execute all fix tasks
332
+ clean_general
333
+ fix_javascript
334
+ fix_python
335
+ fix_go
336
+ fix_java
337
+ fix_config_files
338
+ add_license_headers
339
+ organize_files
340
+ security_check
341
+
342
+ # Print summary
343
+ echo ""
344
+ echo "=============================================="
345
+ echo " Fix Summary"
346
+ echo "=============================================="
347
+ echo -e " Fixed: ${GREEN}$FIXED_COUNT${NC}"
348
+ echo -e " Skipped: ${YELLOW}$SKIPPED_COUNT${NC}"
349
+ echo -e " Errors: ${RED}$ERROR_COUNT${NC}"
350
+ echo ""
351
+
352
+ if [ $ERROR_COUNT -gt 0 ]; then
353
+ echo "Warning: Some errors occurred during fixing"
354
+ exit 1
355
+ else
356
+ echo "All fixes completed successfully"
357
+ exit 0
358
+ fi
359
+ }
360
+
361
+ # Run main function
362
+ main "$@"
core_system/code-analyzer.py ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Auto-Guardian: Smart Code Analyzer
4
+ ===================================
5
+ This script analyzes code to detect various issues
6
+ """
7
+
8
+ import json
9
+ import os
10
+ import re
11
+ import subprocess
12
+ import sys
13
+ from dataclasses import dataclass, field
14
+ from datetime import datetime
15
+ from enum import Enum
16
+ from pathlib import Path
17
+ from typing import Optional
18
+
19
+
20
+ class Severity(Enum):
21
+ """Issue severity levels"""
22
+ CRITICAL = "critical"
23
+ HIGH = "high"
24
+ MEDIUM = "medium"
25
+ LOW = "low"
26
+ INFO = "info"
27
+
28
+
29
+ class IssueType(Enum):
30
+ """Types of issues"""
31
+ SYNTAX_ERROR = "syntax_error"
32
+ LINTING_ERROR = "linting_error"
33
+ SECURITY_VULNERABILITY = "security_vulnerability"
34
+ CODE_SMELL = "code_smell"
35
+ DEPRECATED_USAGE = "deprecated_usage"
36
+ PERFORMANCE_ISSUE = "performance_issue"
37
+ STYLE_VIOLATION = "style_violation"
38
+ TYPE_ERROR = "type_error"
39
+ UNUSED_CODE = "unused_code"
40
+ IMPORT_ERROR = "import_error"
41
+
42
+
43
+ @dataclass
44
+ class CodeIssue:
45
+ """Representation of a code issue"""
46
+ file: str
47
+ line: int
48
+ column: int
49
+ severity: Severity
50
+ issue_type: IssueType
51
+ message: str
52
+ rule_id: Optional[str] = None
53
+ suggestion: Optional[str] = None
54
+ fixable: bool = False
55
+
56
+ def to_dict(self) -> dict:
57
+ """Convert issue to dictionary"""
58
+ return {
59
+ "file": self.file,
60
+ "line": self.line,
61
+ "column": self.column,
62
+ "severity": self.severity.value,
63
+ "type": self.issue_type.value,
64
+ "message": self.message,
65
+ "rule_id": self.rule_id,
66
+ "suggestion": self.suggestion,
67
+ "fixable": self.fixable
68
+ }
69
+
70
+
71
+ @dataclass
72
+ class ScanResult:
73
+ """Complete scan result"""
74
+ timestamp: str = field(default_factory=lambda: datetime.now().isoformat())
75
+ files_scanned: int = 0
76
+ issues_found: int = 0
77
+ issues_by_severity: dict = field(default_factory=dict)
78
+ issues_by_type: dict = field(default_factory=dict)
79
+ critical_issues: list = field(default_factory=list)
80
+ auto_fixable_issues: list = field(default_factory=list)
81
+ issues: list = field(default_factory=list)
82
+
83
+ def to_dict(self) -> dict:
84
+ """Convert result to dictionary"""
85
+ return {
86
+ "timestamp": self.timestamp,
87
+ "summary": {
88
+ "files_scanned": self.files_scanned,
89
+ "total_issues": self.issues_found,
90
+ "by_severity": self.issues_by_severity,
91
+ "by_type": self.issues_by_type,
92
+ "critical_count": len(self.critical_issues),
93
+ "auto_fixable_count": len(self.auto_fixable_issues)
94
+ },
95
+ "critical_issues": [i.to_dict() for i in self.critical_issues],
96
+ "auto_fixable_issues": [i.to_dict() for i in self.auto_fixable_issues],
97
+ "all_issues": [i.to_dict() for i in self.issues]
98
+ }
99
+
100
+
101
+ class CodeAnalyzer:
102
+ """Main code analyzer"""
103
+
104
+ def __init__(self, project_root: str = None):
105
+ self.project_root = Path(project_root) if project_root else Path.cwd()
106
+ self.issues: list[CodeIssue] = []
107
+ self.result = ScanResult()
108
+
109
+ def scan_python(self) -> list[CodeIssue]:
110
+ """Scan Python files"""
111
+ issues = []
112
+
113
+ # Find Python files
114
+ py_files = list(self.project_root.rglob("*.py"))
115
+ self.result.files_scanned += len(py_files)
116
+
117
+ for py_file in py_files:
118
+ try:
119
+ content = py_file.read_text(encoding='utf-8')
120
+ lines = content.split('\n')
121
+
122
+ for line_num, line in enumerate(lines, 1):
123
+ # Check common formatting errors
124
+ if re.search(r'print\s*\([^)]*\)', line):
125
+ issues.append(CodeIssue(
126
+ file=str(py_file),
127
+ line=line_num,
128
+ column=line.find('print'),
129
+ severity=Severity.LOW,
130
+ issue_type=IssueType.CODE_SMELL,
131
+ message="print() usage for debugging",
132
+ suggestion="Use logger instead of print",
133
+ fixable=True
134
+ ))
135
+
136
+ # Check unused variables
137
+ if re.match(r'^\s*_+\w*$', line.strip()):
138
+ issues.append(CodeIssue(
139
+ file=str(py_file),
140
+ line=line_num,
141
+ column=0,
142
+ severity=Severity.INFO,
143
+ issue_type=IssueType.UNUSED_CODE,
144
+ message="Unused variable",
145
+ fixable=True
146
+ ))
147
+
148
+ # Check syntax errors
149
+ try:
150
+ import ast
151
+ ast.parse(content)
152
+ except SyntaxError as e:
153
+ issues.append(CodeIssue(
154
+ file=str(py_file),
155
+ line=e.lineno or 1,
156
+ column=e.offset or 0,
157
+ severity=Severity.CRITICAL,
158
+ issue_type=IssueType.SYNTAX_ERROR,
159
+ message=f"Syntax error: {e.msg}",
160
+ suggestion="Review syntax on this line",
161
+ fixable=False
162
+ ))
163
+
164
+ # Check security vulnerabilities
165
+ security_patterns = [
166
+ (r"os\.environ\[['\"]\w+['\"]\]", "Direct environment variable access", Severity.HIGH, True),
167
+ (r"eval\s*\(", "Unsafe eval() usage", Severity.CRITICAL, False),
168
+ (r"exec\s*\(", "Unsafe exec() usage", Severity.CRITICAL, False),
169
+ (r"pickle\.load", "pickle.load may be unsafe", Severity.MEDIUM, True),
170
+ (r"yaml\.load", "yaml.load without SafeLoader", Severity.HIGH, True),
171
+ (r"password\s*=", "Password in code", Severity.HIGH, False),
172
+ (r"secret\s*=", "Secret key in code", Severity.HIGH, False),
173
+ (r"api[_-]?key\s*=", "API key in code", Severity.HIGH, False),
174
+ ]
175
+
176
+ for pattern, desc, severity, fixable in security_patterns:
177
+ if re.search(pattern, content):
178
+ line_num = self._find_line_with_pattern(lines, pattern)
179
+ issues.append(CodeIssue(
180
+ file=str(py_file),
181
+ line=line_num,
182
+ column=0,
183
+ severity=severity,
184
+ issue_type=IssueType.SECURITY_VULNERABILITY,
185
+ message=f"Security: {desc}",
186
+ suggestion="Move to .env file",
187
+ fixable=fixable
188
+ ))
189
+
190
+ except Exception as e:
191
+ print(f"Error reading {py_file}: {e}")
192
+
193
+ return issues
194
+
195
+ def scan_javascript(self) -> list[CodeIssue]:
196
+ """Scan JavaScript files"""
197
+ issues = []
198
+ js_files = list(self.project_root.rglob("*.js")) + list(self.project_root.rglob("*.ts"))
199
+
200
+ for js_file in js_files:
201
+ try:
202
+ content = js_file.read_text(encoding='utf-8')
203
+ lines = content.split('\n')
204
+
205
+ # Check == instead of ===
206
+ for line_num, line in enumerate(lines, 1):
207
+ if re.search(r'[^=!]==[^=]', line):
208
+ issues.append(CodeIssue(
209
+ file=str(js_file),
210
+ line=line_num,
211
+ column=line.find('=='),
212
+ severity=Severity.MEDIUM,
213
+ issue_type=IssueType.CODE_SMELL,
214
+ message="Use === instead of ==",
215
+ suggestion="Use === for strict comparison",
216
+ fixable=True
217
+ ))
218
+
219
+ # Check var instead of let/const
220
+ if re.search(r'\bvar\s+\w+', line):
221
+ issues.append(CodeIssue(
222
+ file=str(js_file),
223
+ line=line_num,
224
+ column=line.find('var'),
225
+ severity=Severity.LOW,
226
+ issue_type=IssueType.DEPRECATED_USAGE,
227
+ message="Use let/const instead of var",
228
+ suggestion="Use let or const",
229
+ fixable=True
230
+ ))
231
+
232
+ # Check console.log
233
+ if re.search(r'console\.(log|debug|info)', line):
234
+ issues.append(CodeIssue(
235
+ file=str(js_file),
236
+ line=line_num,
237
+ column=line.find('console'),
238
+ severity=Severity.INFO,
239
+ issue_type=IssueType.CODE_SMELL,
240
+ message="Remaining console.log statement",
241
+ suggestion="Remove or use logger",
242
+ fixable=True
243
+ ))
244
+
245
+ except Exception as e:
246
+ print(f"Error reading {js_file}: {e}")
247
+
248
+ return issues
249
+
250
+ def _find_line_with_pattern(self, lines: list[str], pattern: str) -> int:
251
+ """Find line containing pattern"""
252
+ for line_num, line in enumerate(lines, 1):
253
+ if re.search(pattern, line):
254
+ return line_num
255
+ return 1
256
+
257
+ def run_linters(self) -> list[CodeIssue]:
258
+ """Run external linting tools"""
259
+ issues = []
260
+
261
+ # Run Flake8 for Python
262
+ try:
263
+ result = subprocess.run(
264
+ ['flake8', '.', '--format=json', '--max-line-length=100'],
265
+ capture_output=True,
266
+ text=True,
267
+ cwd=self.project_root
268
+ )
269
+ if result.returncode != 0:
270
+ data = json.loads(result.stdout) if result.stdout else []
271
+ for item in data:
272
+ issues.append(CodeIssue(
273
+ file=item['filename'],
274
+ line=item['line_number'],
275
+ column=item['column_number'],
276
+ severity=self._map_flake8_severity(item['type']),
277
+ issue_type=IssueType.LINTING_ERROR,
278
+ message=item['text'],
279
+ rule_id=item['id'],
280
+ fixable=True
281
+ ))
282
+ except Exception as e:
283
+ print(f"Flake8 not available: {e}")
284
+
285
+ # Run ESLint if available
286
+ try:
287
+ result = subprocess.run(
288
+ ['npx', 'eslint', '.', '--format=json'],
289
+ capture_output=True,
290
+ text=True,
291
+ cwd=self.project_root,
292
+ timeout=60
293
+ )
294
+ if result.returncode != 0:
295
+ data = json.loads(result.stdout) if result.stdout else []
296
+ for item in data:
297
+ for msg in item.get('messages', []):
298
+ issues.append(CodeIssue(
299
+ file=item['filePath'],
300
+ line=msg['line'],
301
+ column=msg['column'],
302
+ severity=self._map_eslint_severity(msg['severity']),
303
+ issue_type=IssueType.LINTING_ERROR,
304
+ message=msg['message'],
305
+ rule_id=msg['ruleId'],
306
+ fixable=msg.get('fix') is not None
307
+ ))
308
+ except Exception as e:
309
+ print(f"ESLint not available: {e}")
310
+
311
+ return issues
312
+
313
+ def _map_flake8_severity(self, code: str) -> Severity:
314
+ """Map severity from Flake8 code"""
315
+ prefix = code[0] if code else 'W'
316
+ if prefix == 'E':
317
+ return Severity.HIGH
318
+ elif prefix == 'F':
319
+ return Severity.CRITICAL
320
+ elif prefix == 'W':
321
+ return Severity.LOW
322
+ return Severity.MEDIUM
323
+
324
+ def _map_eslint_severity(self, severity: int) -> Severity:
325
+ """Map severity from ESLint"""
326
+ if severity == 2:
327
+ return Severity.HIGH
328
+ elif severity == 1:
329
+ return Severity.MEDIUM
330
+ return Severity.LOW
331
+
332
+ def analyze(self) -> ScanResult:
333
+ """Run complete analysis"""
334
+ print("Starting code analysis...")
335
+
336
+ # Collect issues from all sources
337
+ python_issues = self.scan_python()
338
+ js_issues = self.scan_javascript()
339
+ linter_issues = self.run_linters()
340
+
341
+ self.issues = python_issues + js_issues + linter_issues
342
+ self.result.issues = self.issues
343
+ self.result.issues_found = len(self.issues)
344
+
345
+ # Categorize issues
346
+ for issue in self.issues:
347
+ # By severity
348
+ severity_key = issue.severity.value
349
+ self.result.issues_by_severity[severity_key] = \
350
+ self.result.issues_by_severity.get(severity_key, 0) + 1
351
+
352
+ # By type
353
+ type_key = issue.issue_type.value
354
+ self.result.issues_by_type[type_key] = \
355
+ self.result.issues_by_type.get(type_key, 0) + 1
356
+
357
+ # Critical issues
358
+ if issue.severity == Severity.CRITICAL:
359
+ self.result.critical_issues.append(issue)
360
+
361
+ # Auto-fixable issues
362
+ if issue.fixable:
363
+ self.result.auto_fixable_issues.append(issue)
364
+
365
+ # Print summary
366
+ print(f" Files scanned: {self.result.files_scanned}")
367
+ print(f" Issues found: {self.result.issues_found}")
368
+ print(f" Critical issues: {len(self.result.critical_issues)}")
369
+ print(f" Auto-fixable issues: {len(self.result.auto_fixable_issues)}")
370
+
371
+ return self.result
372
+
373
+
374
+ def main():
375
+ """Main function"""
376
+ import argparse
377
+
378
+ parser = argparse.ArgumentParser(description='Auto-Guardian Code Analyzer')
379
+ parser.add_argument('--output', '-o', help='Output file', default='scan-results.json')
380
+ parser.add_argument('--format', '-f', choices=['json', 'sarif'], default='json',
381
+ help='Output format')
382
+ parser.add_argument('--project-root', '-p', help='Project directory')
383
+
384
+ args = parser.parse_args()
385
+
386
+ # Create analyzer and run it
387
+ analyzer = CodeAnalyzer(args.project_root)
388
+ result = analyzer.analyze()
389
+
390
+ # Save results
391
+ output_path = Path(args.output)
392
+ output_path.parent.mkdir(parents=True, exist_ok=True)
393
+
394
+ if args.format == 'json':
395
+ with open(output_path, 'w', encoding='utf-8') as f:
396
+ json.dump(result.to_dict(), f, indent=2, ensure_ascii=False)
397
+ print(f" Results saved to {output_path}")
398
+
399
+ # Save critical issues file
400
+ if result.critical_issues:
401
+ critical_path = Path("critical-issues.json")
402
+ with open(critical_path, 'w', encoding='utf-8') as f:
403
+ json.dump([i.to_dict() for i in result.critical_issues], f, indent=2, ensure_ascii=False)
404
+ print(f" Critical issues saved to {critical_path}")
405
+
406
+ # Return exit code based on critical issues
407
+ sys.exit(1 if len(result.critical_issues) > 0 else 0)
408
+
409
+
410
+ if __name__ == '__main__':
411
+ main()
core_system/pyproject.toml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.black]
2
+ line-length = 100
3
+ target-version = ['py39', 'py310', 'py311']
4
+ include = '\.pyi?$'
5
+ extend-exclude = '''
6
+ /(
7
+ \.eggs
8
+ | \.git
9
+ | \.hg
10
+ | \.mypy_cache
11
+ | \.tox
12
+ | \.venv
13
+ | _build
14
+ | buck-out
15
+ | build
16
+ | dist
17
+ )/
18
+ '''
19
+
20
+ [tool.isort]
21
+ profile = "black"
22
+ line_length = 100
23
+ skip = [".venv", "venv", "node_modules"]
24
+ known_first_party = ["app", "src"]
25
+
26
+ [tool.pytest.ini_options]
27
+ testpaths = ["tests"]
28
+ python_files = ["test_*.py"]
29
+ python_functions = ["test_*"]
30
+ addopts = "-v --tb=short"
31
+
32
+ [tool.mypy]
33
+ python_version = "3.11"
34
+ warn_return_any = true
35
+ warn_unused_configs = true
36
+ ignore_missing_imports = true
core_system/report-generator.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Auto-Guardian: Report Generator
4
+ ================================
5
+ Generate detailed reports about code quality and send appropriate notifications
6
+ """
7
+
8
+ import json
9
+ import sys
10
+ from dataclasses import dataclass, field
11
+ from datetime import datetime
12
+ from enum import Enum
13
+ from pathlib import Path
14
+ from typing import Optional
15
+
16
+
17
+ class ReportType(Enum):
18
+ """Types of reports"""
19
+ PULL_REQUEST = "pull_request"
20
+ DAILY_SUMMARY = "daily_summary"
21
+ SECURITY_ALERT = "security_alert"
22
+ QUALITY_REPORT = "quality_report"
23
+
24
+
25
+ @dataclass
26
+ class ReportConfig:
27
+ """Report configuration"""
28
+ scan_results_file: str
29
+ pr_number: Optional[int] = None
30
+ report_type: ReportType = ReportType.PULL_REQUEST
31
+ include_details: bool = True
32
+ include_suggestions: bool = True
33
+
34
+
35
+ class ReportGenerator:
36
+ """Report generator"""
37
+
38
+ def __init__(self, config: ReportConfig):
39
+ self.config = config
40
+ self.results = self._load_results()
41
+
42
+ def _load_results(self) -> dict:
43
+ """Load scan results"""
44
+ with open(self.config.scan_results_file, 'r', encoding='utf-8') as f:
45
+ return json.load(f)
46
+
47
+ def generate_pull_request_comment(self) -> str:
48
+ """Generate comment for Pull Request"""
49
+ summary = self.results.get('summary', {})
50
+ critical_issues = self.results.get('critical_issues', [])
51
+ auto_fixable = self.results.get('auto_fixable_issues', [])
52
+ all_issues = self.results.get('all_issues', [])
53
+
54
+ # Severity emojis
55
+ severity_emojis = {
56
+ 'critical': 'Critical',
57
+ 'high': 'High',
58
+ 'medium': 'Medium',
59
+ 'low': 'Low',
60
+ 'info': 'Info'
61
+ }
62
+
63
+ report = []
64
+
65
+ # Title
66
+ report.append("## Quality Scan Report - Auto-Guardian")
67
+ report.append("")
68
+ report.append(f"**Scan Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
69
+ report.append(f"**Files Scanned:** {summary.get('files_scanned', 0)}")
70
+ report.append(f"**Total Issues:** {summary.get('total_issues', 0)}")
71
+ report.append("")
72
+
73
+ # Summary by severity
74
+ report.append("### Issues Summary")
75
+ report.append("")
76
+ report.append("| Severity | Count |")
77
+ report.append("|----------|-------|")
78
+ for severity, count in summary.get('by_severity', {}).items():
79
+ emoji = severity_emojis.get(severity, 'Info')
80
+ report.append(f"| {emoji} | {count} |")
81
+ report.append("")
82
+
83
+ # Auto-fix status
84
+ if auto_fixable:
85
+ report.append("### Auto-Fixes Applied")
86
+ report.append("")
87
+ report.append(f"**{len(auto_fixable)}** issues were fixed automatically:")
88
+ report.append("")
89
+
90
+ for issue in auto_fixable[:10]: # Show first 10 only
91
+ file_path = Path(issue['file']).name
92
+ report.append(f"- Fixed `{file_path}`:{issue['line']} - {issue['message']}")
93
+
94
+ if len(auto_fixable) > 10:
95
+ report.append(f"- ... and **{len(auto_fixable) - 10}** more fixes")
96
+ report.append("")
97
+
98
+ # Issues requiring human intervention
99
+ if critical_issues:
100
+ report.append("### Issues Requiring Human Intervention")
101
+ report.append("")
102
+ report.append("**This code cannot be merged until these issues are resolved:**")
103
+ report.append("")
104
+
105
+ for issue in critical_issues:
106
+ file_path = Path(issue['file']).name
107
+ emoji = severity_emojis.get(issue['severity'], 'Critical')
108
+ report.append(f"- **{emoji} {issue['file']}:{issue['line']}**")
109
+ report.append(f" - Issue: {issue['message']}")
110
+ if issue.get('suggestion'):
111
+ report.append(f" - Suggestion: {issue['suggestion']}")
112
+ report.append("")
113
+
114
+ report.append("---")
115
+ report.append("### Merge Status: Blocked")
116
+ report.append("")
117
+ report.append("**This Pull Request is blocked from merging due to critical issues.**")
118
+ report.append("")
119
+ report.append("Please resolve the issues above and try again.")
120
+ else:
121
+ # No critical issues
122
+ report.append("---")
123
+ report.append("### Merge Status: Approved")
124
+ report.append("")
125
+ report.append("**This code passed all quality checks!**")
126
+ report.append("")
127
+ report.append("You can proceed with merging this Pull Request.")
128
+
129
+ # Footer
130
+ report.append("")
131
+ report.append("---")
132
+ report.append("*Report generated automatically by Auto-Guardian Bot*")
133
+
134
+ return '\n'.join(report)
135
+
136
+ def generate_daily_summary(self) -> dict:
137
+ """Generate daily summary"""
138
+ summary = self.results.get('summary', {})
139
+
140
+ return {
141
+ "date": datetime.now().isoformat(),
142
+ "total_issues": summary.get('total_issues', 0),
143
+ "critical_issues": summary.get('critical_count', 0),
144
+ "auto_fixed": summary.get('auto_fixable_count', 0),
145
+ "by_severity": summary.get('by_severity', {}),
146
+ "by_type": summary.get('by_type', {})
147
+ }
148
+
149
+ def generate_security_alert(self) -> str:
150
+ """Generate security alert"""
151
+ critical = self.results.get('critical_issues', [])
152
+ security_issues = [i for i in critical if 'security' in i.get('type', '')]
153
+
154
+ if not security_issues:
155
+ return None
156
+
157
+ alert = []
158
+ alert.append("Security Alert - Auto-Guardian")
159
+ alert.append("")
160
+ alert.append("Security vulnerabilities detected in code:")
161
+ alert.append("")
162
+
163
+ for issue in security_issues:
164
+ alert.append(f"- {issue['file']}:{issue['line']}")
165
+ alert.append(f" {issue['message']}")
166
+ if issue.get('suggestion'):
167
+ alert.append(f" Suggestion: {issue['suggestion']}")
168
+
169
+ return '\n'.join(alert)
170
+
171
+ def save_report(self, content: str, filename: str = "report.md") -> Path:
172
+ """Save report to file"""
173
+ output_path = Path(filename)
174
+ with open(output_path, 'w', encoding='utf-8') as f:
175
+ f.write(content)
176
+ return output_path
177
+
178
+
179
+ def main():
180
+ """Main function"""
181
+ import argparse
182
+
183
+ parser = argparse.ArgumentParser(description='Auto-Guardian Report Generator')
184
+ parser.add_argument('--scan-results', required=True, help='Scan results file')
185
+ parser.add_argument('--pr-number', type=int, help='Pull Request number')
186
+ parser.add_argument('--output', '-o', default="report.md", help='Output file')
187
+ parser.add_argument('--format', choices=['comment', 'summary', 'json'],
188
+ default='comment', help='Report format')
189
+
190
+ args = parser.parse_args()
191
+
192
+ config = ReportConfig(
193
+ scan_results_file=args.scan_results,
194
+ pr_number=args.pr_number,
195
+ report_type=ReportType.PULL_REQUEST
196
+ )
197
+
198
+ generator = ReportGenerator(config)
199
+
200
+ if args.format == 'comment':
201
+ report = generator.generate_pull_request_comment()
202
+ elif args.format == 'summary':
203
+ report = json.dumps(generator.generate_daily_summary(), indent=2)
204
+ else:
205
+ report = generator.generate_pull_request_comment()
206
+
207
+ # Print report
208
+ print(report)
209
+
210
+ # Save report
211
+ generator.save_report(report, args.output)
212
+ print(f"\nReport saved to {args.output}")
213
+
214
+
215
+ if __name__ == '__main__':
216
+ main()
core_system/requirements.txt ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Analysis and linting tools
2
+ flake8>=6.0.0
3
+ pylint>=2.17.0
4
+ mypy>=1.4.0
5
+ black>=23.0.0
6
+ isort>=5.12.0
7
+ autoflake>=2.0.0
8
+
9
+ # Security tools
10
+ bandit>=1.7.0
11
+ safety>=2.3.0
12
+
13
+ # Testing tools
14
+ pytest>=7.4.0
15
+ pytest-cov>=4.1.0
16
+
17
+ # Helper tools
18
+ pyyaml>=6.0
19
+ rich>=13.0.0