antigravity-devkit 1.0.2 → 1.0.4

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 (60) hide show
  1. package/README.md +153 -26
  2. package/package.json +2 -2
  3. package/template/ARCHITECTURE.md +0 -148
  4. package/template/README.md +0 -421
  5. package/template/agents/backend-specialist.md +0 -137
  6. package/template/agents/database-architect.md +0 -114
  7. package/template/agents/debugger.md +0 -108
  8. package/template/agents/devops-engineer.md +0 -125
  9. package/template/agents/documentation-writer.md +0 -109
  10. package/template/agents/explorer-agent.md +0 -107
  11. package/template/agents/frontend-specialist.md +0 -231
  12. package/template/agents/orchestrator.md +0 -100
  13. package/template/agents/performance-optimizer.md +0 -109
  14. package/template/agents/project-planner.md +0 -123
  15. package/template/agents/security-auditor.md +0 -107
  16. package/template/agents/test-engineer.md +0 -133
  17. package/template/rules/GEMINI.md +0 -180
  18. package/template/scripts/README.md +0 -317
  19. package/template/scripts/checklist.py +0 -170
  20. package/template/scripts/lint_runner.py +0 -253
  21. package/template/scripts/schema_validator.py +0 -277
  22. package/template/scripts/security_scan.py +0 -354
  23. package/template/scripts/verify_all.py +0 -243
  24. package/template/scripts/vitest_runner.py +0 -203
  25. package/template/scripts/xunit_runner.py +0 -235
  26. package/template/skills/api-patterns/SKILL.md +0 -116
  27. package/template/skills/architecture/SKILL.md +0 -98
  28. package/template/skills/aspnet-patterns/SKILL.md +0 -122
  29. package/template/skills/azure-aks/SKILL.md +0 -136
  30. package/template/skills/azure-devops/SKILL.md +0 -123
  31. package/template/skills/azure-keyvault/SKILL.md +0 -100
  32. package/template/skills/brainstorming/SKILL.md +0 -96
  33. package/template/skills/clean-code/SKILL.md +0 -84
  34. package/template/skills/csharp-patterns/SKILL.md +0 -155
  35. package/template/skills/documentation-templates/SKILL.md +0 -127
  36. package/template/skills/frontend-design/SKILL.md +0 -199
  37. package/template/skills/frontend-design/animation-guide.md +0 -217
  38. package/template/skills/frontend-design/design-systems.md +0 -230
  39. package/template/skills/frontend-design/ux-psychology.md +0 -128
  40. package/template/skills/gitops-patterns/SKILL.md +0 -105
  41. package/template/skills/grafana-logging/SKILL.md +0 -107
  42. package/template/skills/intelligent-routing/SKILL.md +0 -75
  43. package/template/skills/plan-writing/SKILL.md +0 -96
  44. package/template/skills/sqlserver-design/SKILL.md +0 -97
  45. package/template/skills/systematic-debugging/SKILL.md +0 -98
  46. package/template/skills/testing-patterns/SKILL.md +0 -102
  47. package/template/skills/vitest-testing/SKILL.md +0 -116
  48. package/template/skills/vue3-patterns/SKILL.md +0 -235
  49. package/template/skills/vulnerability-scanner/SKILL.md +0 -104
  50. package/template/skills/xunit-testing/SKILL.md +0 -127
  51. package/template/workflows/brainstorm.md +0 -69
  52. package/template/workflows/code.md +0 -82
  53. package/template/workflows/create.md +0 -79
  54. package/template/workflows/debug.md +0 -83
  55. package/template/workflows/deploy.md +0 -101
  56. package/template/workflows/orchestrate.md +0 -86
  57. package/template/workflows/plan.md +0 -79
  58. package/template/workflows/review.md +0 -85
  59. package/template/workflows/status.md +0 -90
  60. package/template/workflows/test.md +0 -89
@@ -1,354 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Security Scanner - Security vulnerability detection and analysis
4
- Used by security-auditor agent to scan for security issues.
5
-
6
- Usage:
7
- python security_scan.py <project_path>
8
- python security_scan.py <project_path> --severity high
9
- """
10
-
11
- import subprocess
12
- import sys
13
- import re
14
- import json
15
- from pathlib import Path
16
- from typing import Tuple, Dict, Any, List
17
-
18
-
19
- def run_command(cmd: list[str], cwd: str = ".") -> Tuple[int, str]:
20
- """Run a command and return exit code and output."""
21
- try:
22
- result = subprocess.run(
23
- cmd,
24
- cwd=cwd,
25
- capture_output=True,
26
- text=True,
27
- timeout=300
28
- )
29
- return result.returncode, result.stdout + result.stderr
30
- except subprocess.TimeoutExpired:
31
- return 1, "Command timed out after 5 minutes"
32
- except FileNotFoundError:
33
- return 1, f"Command not found: {cmd[0]}"
34
-
35
-
36
- def scan_hardcoded_secrets(project_path: str) -> List[Dict[str, str]]:
37
- """Scan for hardcoded secrets and credentials."""
38
- findings = []
39
- path = Path(project_path)
40
-
41
- # Patterns to search for
42
- secret_patterns = {
43
- 'password': r'password\s*=\s*["\'](?!.*\{.*\})([^"\']+)["\']',
44
- 'api_key': r'(api[_-]?key|apikey)\s*[=:]\s*["\']([^"\']+)["\']',
45
- 'secret': r'secret\s*[=:]\s*["\'](?!.*\{.*\})([^"\']+)["\']',
46
- 'token': r'(access[_-]?token|auth[_-]?token)\s*[=:]\s*["\']([^"\']+)["\']',
47
- 'connection_string': r'(connectionstring|connection[_-]string)\s*[=:]\s*["\'](?!.*\{.*\})([^"\']+)["\']',
48
- 'private_key': r'(private[_-]?key|privatekey)\s*[=:]\s*["\']([^"\']+)["\']',
49
- }
50
-
51
- # File extensions to scan
52
- extensions = ['.cs', '.ts', '.js', '.vue', '.json', '.config', '.yaml', '.yml']
53
-
54
- for ext in extensions:
55
- for file_path in path.glob(f"**/*{ext}"):
56
- # Skip node_modules, bin, obj directories
57
- if any(skip in str(file_path) for skip in ['node_modules', 'bin', 'obj', '.git']):
58
- continue
59
-
60
- try:
61
- with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
62
- content = f.read()
63
-
64
- for pattern_name, pattern in secret_patterns.items():
65
- matches = re.finditer(pattern, content, re.IGNORECASE)
66
- for match in matches:
67
- # Skip if it looks like a placeholder or environment variable
68
- matched_value = match.group(0)
69
- if any(skip in matched_value.lower() for skip in ['example', 'placeholder', 'your_', 'xxx', '***', 'env.']):
70
- continue
71
-
72
- findings.append({
73
- 'type': pattern_name,
74
- 'file': str(file_path.relative_to(path)),
75
- 'line': content[:match.start()].count('\n') + 1,
76
- 'severity': 'HIGH',
77
- 'message': f'Potential hardcoded {pattern_name.replace("_", " ")}'
78
- })
79
- except Exception:
80
- continue
81
-
82
- return findings
83
-
84
-
85
- def scan_npm_vulnerabilities(project_path: str) -> List[Dict[str, str]]:
86
- """Scan npm packages for known vulnerabilities."""
87
- findings = []
88
- package_json = Path(project_path) / "package.json"
89
-
90
- if not package_json.exists():
91
- return findings
92
-
93
- # Run npm audit
94
- code, output = run_command(["npm", "audit", "--json"], project_path)
95
-
96
- try:
97
- audit_data = json.loads(output)
98
-
99
- # Parse vulnerabilities
100
- if 'vulnerabilities' in audit_data:
101
- for pkg_name, vuln_info in audit_data['vulnerabilities'].items():
102
- severity = vuln_info.get('severity', 'unknown').upper()
103
-
104
- findings.append({
105
- 'type': 'npm_vulnerability',
106
- 'file': 'package.json',
107
- 'package': pkg_name,
108
- 'severity': severity,
109
- 'message': f"{pkg_name}: {vuln_info.get('via', ['Unknown issue'])[0] if isinstance(vuln_info.get('via'), list) else 'Vulnerability detected'}"
110
- })
111
- except json.JSONDecodeError:
112
- # Fallback to text parsing
113
- if 'vulnerabilities' in output.lower():
114
- findings.append({
115
- 'type': 'npm_vulnerability',
116
- 'file': 'package.json',
117
- 'severity': 'UNKNOWN',
118
- 'message': 'npm audit found vulnerabilities (run npm audit for details)'
119
- })
120
-
121
- return findings
122
-
123
-
124
- def scan_dotnet_vulnerabilities(project_path: str) -> List[Dict[str, str]]:
125
- """Scan .NET packages for known vulnerabilities."""
126
- findings = []
127
-
128
- # Check if dotnet is available
129
- code, _ = run_command(["dotnet", "--version"])
130
- if code != 0:
131
- return findings
132
-
133
- # Run dotnet list package --vulnerable
134
- code, output = run_command(["dotnet", "list", "package", "--vulnerable"], project_path)
135
-
136
- if code == 0 and output:
137
- lines = output.split('\n')
138
- for line in lines:
139
- if 'vulnerable' in line.lower() or 'severity' in line.lower():
140
- findings.append({
141
- 'type': 'nuget_vulnerability',
142
- 'file': 'packages',
143
- 'severity': 'MEDIUM',
144
- 'message': line.strip()
145
- })
146
-
147
- return findings
148
-
149
-
150
- def scan_insecure_patterns(project_path: str) -> List[Dict[str, str]]:
151
- """Scan for insecure coding patterns."""
152
- findings = []
153
- path = Path(project_path)
154
-
155
- insecure_patterns = {
156
- 'sql_injection': {
157
- 'pattern': r'(ExecuteRawSql|FromSqlRaw|ExecuteSqlCommand)\s*\([^)]*\+',
158
- 'message': 'Potential SQL injection - avoid string concatenation in SQL queries',
159
- 'severity': 'HIGH'
160
- },
161
- 'xss': {
162
- 'pattern': r'innerHTML\s*=\s*(?!["\']\s*["\'])',
163
- 'message': 'Potential XSS vulnerability - avoid innerHTML with user input',
164
- 'severity': 'HIGH'
165
- },
166
- 'weak_crypto': {
167
- 'pattern': r'(MD5|SHA1)\.Create\(',
168
- 'message': 'Weak cryptographic algorithm - use SHA256 or stronger',
169
- 'severity': 'MEDIUM'
170
- },
171
- 'eval_usage': {
172
- 'pattern': r'\beval\s*\(',
173
- 'message': 'Dangerous eval() usage - avoid evaluating dynamic code',
174
- 'severity': 'HIGH'
175
- },
176
- 'http_not_https': {
177
- 'pattern': r'http://(?!localhost|127\.0\.0\.1)',
178
- 'message': 'HTTP URL detected - use HTTPS for external resources',
179
- 'severity': 'MEDIUM'
180
- }
181
- }
182
-
183
- extensions = ['.cs', '.ts', '.js', '.vue']
184
-
185
- for ext in extensions:
186
- for file_path in path.glob(f"**/*{ext}"):
187
- if any(skip in str(file_path) for skip in ['node_modules', 'bin', 'obj', '.git']):
188
- continue
189
-
190
- try:
191
- with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
192
- content = f.read()
193
-
194
- for pattern_name, pattern_info in insecure_patterns.items():
195
- matches = re.finditer(pattern_info['pattern'], content, re.IGNORECASE)
196
- for match in matches:
197
- findings.append({
198
- 'type': pattern_name,
199
- 'file': str(file_path.relative_to(path)),
200
- 'line': content[:match.start()].count('\n') + 1,
201
- 'severity': pattern_info['severity'],
202
- 'message': pattern_info['message']
203
- })
204
- except Exception:
205
- continue
206
-
207
- return findings
208
-
209
-
210
- def check_security_headers(project_path: str) -> List[Dict[str, str]]:
211
- """Check for security header configurations."""
212
- findings = []
213
- path = Path(project_path)
214
-
215
- # Check for ASP.NET security configurations
216
- startup_files = list(path.glob("**/Startup.cs")) + list(path.glob("**/Program.cs"))
217
-
218
- for startup_file in startup_files:
219
- try:
220
- with open(startup_file, 'r', encoding='utf-8') as f:
221
- content = f.read()
222
-
223
- # Check for HSTS
224
- if 'UseHsts' not in content:
225
- findings.append({
226
- 'type': 'missing_hsts',
227
- 'file': str(startup_file.relative_to(path)),
228
- 'severity': 'MEDIUM',
229
- 'message': 'HSTS not configured - add app.UseHsts()'
230
- })
231
-
232
- # Check for HTTPS redirection
233
- if 'UseHttpsRedirection' not in content:
234
- findings.append({
235
- 'type': 'missing_https_redirect',
236
- 'file': str(startup_file.relative_to(path)),
237
- 'severity': 'MEDIUM',
238
- 'message': 'HTTPS redirection not configured'
239
- })
240
- except Exception:
241
- continue
242
-
243
- return findings
244
-
245
-
246
- def format_report(all_findings: List[Dict[str, str]], severity_filter: str = None) -> Tuple[str, int]:
247
- """Format security scan report."""
248
- # Filter by severity if specified
249
- if severity_filter:
250
- all_findings = [f for f in all_findings if f['severity'] == severity_filter.upper()]
251
-
252
- # Group by severity
253
- by_severity = {'HIGH': [], 'MEDIUM': [], 'LOW': [], 'UNKNOWN': []}
254
- for finding in all_findings:
255
- severity = finding.get('severity', 'UNKNOWN')
256
- by_severity[severity].append(finding)
257
-
258
- report = []
259
- report.append("=" * 60)
260
- report.append("🔒 SECURITY SCAN REPORT")
261
- report.append("=" * 60)
262
-
263
- report.append("")
264
- report.append("📊 Summary:")
265
- report.append(f" Total findings: {len(all_findings)}")
266
- report.append(f" HIGH: {len(by_severity['HIGH'])} 🔴")
267
- report.append(f" MEDIUM: {len(by_severity['MEDIUM'])} 🟡")
268
- report.append(f" LOW: {len(by_severity['LOW'])} 🟢")
269
-
270
- # Report HIGH severity issues
271
- if by_severity['HIGH']:
272
- report.append("")
273
- report.append("🔴 HIGH Severity Issues:")
274
- for finding in by_severity['HIGH'][:15]:
275
- report.append(f" • {finding['file']}:{finding.get('line', '?')}")
276
- report.append(f" {finding['message']}")
277
- if len(by_severity['HIGH']) > 15:
278
- report.append(f" ... and {len(by_severity['HIGH']) - 15} more")
279
-
280
- # Report MEDIUM severity issues
281
- if by_severity['MEDIUM']:
282
- report.append("")
283
- report.append("🟡 MEDIUM Severity Issues:")
284
- for finding in by_severity['MEDIUM'][:10]:
285
- report.append(f" • {finding['file']}:{finding.get('line', '?')}")
286
- report.append(f" {finding['message']}")
287
- if len(by_severity['MEDIUM']) > 10:
288
- report.append(f" ... and {len(by_severity['MEDIUM']) - 10} more")
289
-
290
- report.append("")
291
- report.append("=" * 60)
292
-
293
- # Determine exit code
294
- if by_severity['HIGH']:
295
- report.append("❌ Security scan failed - HIGH severity issues found")
296
- return "\n".join(report), 1
297
- elif by_severity['MEDIUM']:
298
- report.append("⚠️ Security scan completed with warnings")
299
- return "\n".join(report), 0
300
- else:
301
- report.append("✅ No security issues found")
302
- return "\n".join(report), 0
303
-
304
-
305
- def main():
306
- if len(sys.argv) < 2:
307
- print("Usage: python security_scan.py <project_path> [--severity high|medium|low]")
308
- sys.exit(1)
309
-
310
- project_path = sys.argv[1]
311
- severity_filter = None
312
-
313
- if "--severity" in sys.argv:
314
- sev_index = sys.argv.index("--severity") + 1
315
- if sev_index < len(sys.argv):
316
- severity_filter = sys.argv[sev_index]
317
-
318
- print("🔒 Security Scanner")
319
- print("=" * 60)
320
- print(f"Project: {project_path}")
321
- if severity_filter:
322
- print(f"Severity filter: {severity_filter.upper()}")
323
- print()
324
-
325
- all_findings = []
326
-
327
- # Run scans
328
- print("Scanning for hardcoded secrets...")
329
- all_findings.extend(scan_hardcoded_secrets(project_path))
330
-
331
- print("Scanning npm vulnerabilities...")
332
- all_findings.extend(scan_npm_vulnerabilities(project_path))
333
-
334
- print("Scanning .NET vulnerabilities...")
335
- all_findings.extend(scan_dotnet_vulnerabilities(project_path))
336
-
337
- print("Scanning for insecure patterns...")
338
- all_findings.extend(scan_insecure_patterns(project_path))
339
-
340
- print("Checking security headers...")
341
- all_findings.extend(check_security_headers(project_path))
342
-
343
- print()
344
- print("-" * 60)
345
-
346
- # Generate and print report
347
- report, exit_code = format_report(all_findings, severity_filter)
348
- print(report)
349
-
350
- sys.exit(exit_code)
351
-
352
-
353
- if __name__ == "__main__":
354
- main()
@@ -1,243 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Verify All - Comprehensive project verification
4
- Run before deployment or releases.
5
-
6
- Usage:
7
- python .agent-antigravity/scripts/verify_all.py .
8
- python .agent-antigravity/scripts/verify_all.py . --url http://localhost:3000
9
- """
10
-
11
- import subprocess
12
- import sys
13
- import os
14
- from pathlib import Path
15
- from datetime import datetime
16
-
17
-
18
- def run_command(cmd: list[str], cwd: str = ".") -> tuple[int, str]:
19
- """Run a command and return exit code and output."""
20
- try:
21
- result = subprocess.run(
22
- cmd,
23
- cwd=cwd,
24
- capture_output=True,
25
- text=True,
26
- timeout=600
27
- )
28
- return result.returncode, result.stdout + result.stderr
29
- except subprocess.TimeoutExpired:
30
- return 1, "Command timed out"
31
- except FileNotFoundError:
32
- return 1, f"Command not found: {cmd[0]}"
33
-
34
-
35
- class Verifier:
36
- def __init__(self, project_path: str, url: str = None):
37
- self.project_path = project_path
38
- self.url = url
39
- self.results = []
40
-
41
- def add_result(self, category: str, name: str, passed: bool, details: str = ""):
42
- self.results.append({
43
- "category": category,
44
- "name": name,
45
- "passed": passed,
46
- "details": details
47
- })
48
-
49
- def run_all(self):
50
- """Run all verification checks."""
51
- print("=" * 70)
52
- print("COMPREHENSIVE PROJECT VERIFICATION")
53
- print(f"Started: {datetime.now().isoformat()}")
54
- print("=" * 70)
55
-
56
- self.verify_security()
57
- self.verify_code_quality()
58
- self.verify_tests()
59
- self.verify_build()
60
- self.verify_dependencies()
61
-
62
- if self.url:
63
- self.verify_runtime(self.url)
64
-
65
- self.print_summary()
66
-
67
- def verify_security(self):
68
- """Security verification."""
69
- print("\n[SECURITY]")
70
-
71
- # Check for secrets
72
- secret_patterns = [
73
- ("password", "password="),
74
- ("api_key", "apikey="),
75
- ("secret", "secret="),
76
- ("connection_string", "connectionstring="),
77
- ]
78
-
79
- for name, pattern in secret_patterns:
80
- code, output = run_command(
81
- ["grep", "-ri", pattern, "--include=*.cs", "--include=*.ts"],
82
- self.project_path
83
- )
84
- passed = code != 0 or not output.strip()
85
- self.add_result("Security", f"No hardcoded {name}", passed)
86
- print(f" {'✅' if passed else '❌'} No hardcoded {name}")
87
-
88
- # npm audit
89
- package_json = Path(self.project_path) / "package.json"
90
- if package_json.exists():
91
- code, output = run_command(["npm", "audit", "--audit-level=critical"], self.project_path)
92
- passed = code == 0
93
- self.add_result("Security", "npm audit (critical)", passed, output[:200])
94
- print(f" {'✅' if passed else '❌'} npm audit (critical)")
95
-
96
- def verify_code_quality(self):
97
- """Code quality verification."""
98
- print("\n[CODE QUALITY]")
99
-
100
- # Frontend lint
101
- package_json = Path(self.project_path) / "package.json"
102
- if package_json.exists():
103
- code, output = run_command(["npm", "run", "lint"], self.project_path)
104
- passed = code == 0
105
- self.add_result("Code Quality", "Frontend lint", passed)
106
- print(f" {'✅' if passed else '❌'} Frontend lint")
107
-
108
- # TypeScript
109
- code, output = run_command(["npx", "tsc", "--noEmit"], self.project_path)
110
- passed = code == 0
111
- self.add_result("Code Quality", "TypeScript check", passed)
112
- print(f" {'✅' if passed else '❌'} TypeScript check")
113
-
114
- # Backend lint (if applicable)
115
- csproj_files = list(Path(self.project_path).glob("**/*.csproj"))
116
- if csproj_files:
117
- code, output = run_command(["dotnet", "format", "--verify-no-changes"], self.project_path)
118
- passed = code == 0
119
- self.add_result("Code Quality", "C# formatting", passed)
120
- print(f" {'✅' if passed else '❌'} C# formatting")
121
-
122
- def verify_tests(self):
123
- """Test verification."""
124
- print("\n[TESTS]")
125
-
126
- # Frontend tests
127
- package_json = Path(self.project_path) / "package.json"
128
- if package_json.exists():
129
- code, output = run_command(["npm", "run", "test", "--", "--run"], self.project_path)
130
- passed = code == 0
131
- self.add_result("Tests", "Frontend tests", passed)
132
- print(f" {'✅' if passed else '❌'} Frontend tests")
133
-
134
- # Backend tests
135
- sln_files = list(Path(self.project_path).glob("*.sln"))
136
- if sln_files:
137
- code, output = run_command(["dotnet", "test"], self.project_path)
138
- passed = code == 0
139
- self.add_result("Tests", "Backend tests", passed)
140
- print(f" {'✅' if passed else '❌'} Backend tests")
141
-
142
- def verify_build(self):
143
- """Build verification."""
144
- print("\n[BUILD]")
145
-
146
- # Frontend build
147
- package_json = Path(self.project_path) / "package.json"
148
- if package_json.exists():
149
- code, output = run_command(["npm", "run", "build"], self.project_path)
150
- passed = code == 0
151
- self.add_result("Build", "Frontend build", passed)
152
- print(f" {'✅' if passed else '❌'} Frontend build")
153
-
154
- # Backend build
155
- sln_files = list(Path(self.project_path).glob("*.sln"))
156
- if sln_files:
157
- code, output = run_command(["dotnet", "build", "-c", "Release"], self.project_path)
158
- passed = code == 0
159
- self.add_result("Build", "Backend build", passed)
160
- print(f" {'✅' if passed else '❌'} Backend build")
161
-
162
- def verify_dependencies(self):
163
- """Dependency verification."""
164
- print("\n[DEPENDENCIES]")
165
-
166
- # npm outdated
167
- package_json = Path(self.project_path) / "package.json"
168
- if package_json.exists():
169
- code, output = run_command(["npm", "outdated"], self.project_path)
170
- # outdated returns 1 if there are outdated packages
171
- self.add_result("Dependencies", "npm packages", True, "Check npm outdated for details")
172
- print(f" ℹ️ npm outdated check complete")
173
-
174
- # dotnet outdated (if tool installed)
175
- sln_files = list(Path(self.project_path).glob("*.sln"))
176
- if sln_files:
177
- code, output = run_command(["dotnet", "list", "package", "--outdated"], self.project_path)
178
- self.add_result("Dependencies", "NuGet packages", True, "Check dotnet list package for details")
179
- print(f" ℹ️ NuGet outdated check complete")
180
-
181
- def verify_runtime(self, url: str):
182
- """Runtime verification (if URL provided)."""
183
- print("\n[RUNTIME]")
184
-
185
- # Health check
186
- code, output = run_command(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", f"{url}/health"])
187
- passed = output.strip() == "200"
188
- self.add_result("Runtime", "Health check", passed)
189
- print(f" {'✅' if passed else '❌'} Health check")
190
-
191
- def print_summary(self):
192
- """Print verification summary."""
193
- print("\n" + "=" * 70)
194
- print("VERIFICATION SUMMARY")
195
- print("=" * 70)
196
-
197
- categories = {}
198
- for r in self.results:
199
- cat = r["category"]
200
- if cat not in categories:
201
- categories[cat] = []
202
- categories[cat].append(r)
203
-
204
- total_passed = 0
205
- total_count = 0
206
-
207
- for cat, items in categories.items():
208
- print(f"\n{cat}:")
209
- for item in items:
210
- status = "✅" if item["passed"] else "❌"
211
- print(f" {status} {item['name']}")
212
- total_count += 1
213
- if item["passed"]:
214
- total_passed += 1
215
-
216
- print("\n" + "-" * 70)
217
- print(f"Total: {total_passed}/{total_count} checks passed")
218
-
219
- if total_passed < total_count:
220
- print("\n❌ Some checks failed. Review and fix before deployment.")
221
- sys.exit(1)
222
- else:
223
- print("\n✅ All checks passed! Ready for deployment.")
224
-
225
-
226
- def main():
227
- if len(sys.argv) < 2:
228
- print("Usage: python verify_all.py <project_path> [--url <url>]")
229
- sys.exit(1)
230
-
231
- project_path = sys.argv[1]
232
- url = None
233
- if "--url" in sys.argv:
234
- url_index = sys.argv.index("--url") + 1
235
- if url_index < len(sys.argv):
236
- url = sys.argv[url_index]
237
-
238
- verifier = Verifier(project_path, url)
239
- verifier.run_all()
240
-
241
-
242
- if __name__ == "__main__":
243
- main()