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.
- package/README.md +153 -26
- package/package.json +2 -2
- package/template/ARCHITECTURE.md +0 -148
- package/template/README.md +0 -421
- package/template/agents/backend-specialist.md +0 -137
- package/template/agents/database-architect.md +0 -114
- package/template/agents/debugger.md +0 -108
- package/template/agents/devops-engineer.md +0 -125
- package/template/agents/documentation-writer.md +0 -109
- package/template/agents/explorer-agent.md +0 -107
- package/template/agents/frontend-specialist.md +0 -231
- package/template/agents/orchestrator.md +0 -100
- package/template/agents/performance-optimizer.md +0 -109
- package/template/agents/project-planner.md +0 -123
- package/template/agents/security-auditor.md +0 -107
- package/template/agents/test-engineer.md +0 -133
- package/template/rules/GEMINI.md +0 -180
- package/template/scripts/README.md +0 -317
- package/template/scripts/checklist.py +0 -170
- package/template/scripts/lint_runner.py +0 -253
- package/template/scripts/schema_validator.py +0 -277
- package/template/scripts/security_scan.py +0 -354
- package/template/scripts/verify_all.py +0 -243
- package/template/scripts/vitest_runner.py +0 -203
- package/template/scripts/xunit_runner.py +0 -235
- package/template/skills/api-patterns/SKILL.md +0 -116
- package/template/skills/architecture/SKILL.md +0 -98
- package/template/skills/aspnet-patterns/SKILL.md +0 -122
- package/template/skills/azure-aks/SKILL.md +0 -136
- package/template/skills/azure-devops/SKILL.md +0 -123
- package/template/skills/azure-keyvault/SKILL.md +0 -100
- package/template/skills/brainstorming/SKILL.md +0 -96
- package/template/skills/clean-code/SKILL.md +0 -84
- package/template/skills/csharp-patterns/SKILL.md +0 -155
- package/template/skills/documentation-templates/SKILL.md +0 -127
- package/template/skills/frontend-design/SKILL.md +0 -199
- package/template/skills/frontend-design/animation-guide.md +0 -217
- package/template/skills/frontend-design/design-systems.md +0 -230
- package/template/skills/frontend-design/ux-psychology.md +0 -128
- package/template/skills/gitops-patterns/SKILL.md +0 -105
- package/template/skills/grafana-logging/SKILL.md +0 -107
- package/template/skills/intelligent-routing/SKILL.md +0 -75
- package/template/skills/plan-writing/SKILL.md +0 -96
- package/template/skills/sqlserver-design/SKILL.md +0 -97
- package/template/skills/systematic-debugging/SKILL.md +0 -98
- package/template/skills/testing-patterns/SKILL.md +0 -102
- package/template/skills/vitest-testing/SKILL.md +0 -116
- package/template/skills/vue3-patterns/SKILL.md +0 -235
- package/template/skills/vulnerability-scanner/SKILL.md +0 -104
- package/template/skills/xunit-testing/SKILL.md +0 -127
- package/template/workflows/brainstorm.md +0 -69
- package/template/workflows/code.md +0 -82
- package/template/workflows/create.md +0 -79
- package/template/workflows/debug.md +0 -83
- package/template/workflows/deploy.md +0 -101
- package/template/workflows/orchestrate.md +0 -86
- package/template/workflows/plan.md +0 -79
- package/template/workflows/review.md +0 -85
- package/template/workflows/status.md +0 -90
- package/template/workflows/test.md +0 -89
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Vitest Runner - Frontend test execution and validation
|
|
4
|
-
Used by frontend-specialist agent to run and validate Vue3/TypeScript tests.
|
|
5
|
-
|
|
6
|
-
Usage:
|
|
7
|
-
python vitest_runner.py <project_path>
|
|
8
|
-
python vitest_runner.py <project_path> --coverage
|
|
9
|
-
python vitest_runner.py <project_path> --watch
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import subprocess
|
|
13
|
-
import sys
|
|
14
|
-
import json
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Tuple, Dict, Any
|
|
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 check_vitest_installed(project_path: str) -> Tuple[bool, str]:
|
|
37
|
-
"""Check if Vitest is installed in the project."""
|
|
38
|
-
package_json = Path(project_path) / "package.json"
|
|
39
|
-
|
|
40
|
-
if not package_json.exists():
|
|
41
|
-
return False, "No package.json found in project"
|
|
42
|
-
|
|
43
|
-
try:
|
|
44
|
-
with open(package_json, 'r', encoding='utf-8') as f:
|
|
45
|
-
data = json.load(f)
|
|
46
|
-
deps = {**data.get('dependencies', {}), **data.get('devDependencies', {})}
|
|
47
|
-
|
|
48
|
-
if 'vitest' not in deps:
|
|
49
|
-
return False, "Vitest not found in dependencies"
|
|
50
|
-
|
|
51
|
-
return True, f"Vitest {deps['vitest']} installed"
|
|
52
|
-
except Exception as e:
|
|
53
|
-
return False, f"Error reading package.json: {str(e)}"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def run_vitest(project_path: str, coverage: bool = False, watch: bool = False) -> Tuple[int, str, Dict[str, Any]]:
|
|
57
|
-
"""Run Vitest tests and return results."""
|
|
58
|
-
cmd = ["npm", "run", "test", "--"]
|
|
59
|
-
|
|
60
|
-
if watch:
|
|
61
|
-
cmd.append("--watch")
|
|
62
|
-
else:
|
|
63
|
-
cmd.append("--run")
|
|
64
|
-
|
|
65
|
-
if coverage:
|
|
66
|
-
cmd.append("--coverage")
|
|
67
|
-
|
|
68
|
-
# Add reporter for better parsing
|
|
69
|
-
cmd.extend(["--reporter=verbose"])
|
|
70
|
-
|
|
71
|
-
code, output = run_command(cmd, project_path)
|
|
72
|
-
|
|
73
|
-
# Parse test results
|
|
74
|
-
results = parse_vitest_output(output)
|
|
75
|
-
|
|
76
|
-
return code, output, results
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def parse_vitest_output(output: str) -> Dict[str, Any]:
|
|
80
|
-
"""Parse Vitest output to extract test statistics."""
|
|
81
|
-
results = {
|
|
82
|
-
'total': 0,
|
|
83
|
-
'passed': 0,
|
|
84
|
-
'failed': 0,
|
|
85
|
-
'skipped': 0,
|
|
86
|
-
'duration': 0,
|
|
87
|
-
'coverage': None,
|
|
88
|
-
'errors': []
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
lines = output.split('\n')
|
|
92
|
-
|
|
93
|
-
for line in lines:
|
|
94
|
-
# Parse test counts
|
|
95
|
-
if 'Test Files' in line:
|
|
96
|
-
# Example: "Test Files 2 passed (2)"
|
|
97
|
-
parts = line.split()
|
|
98
|
-
for i, part in enumerate(parts):
|
|
99
|
-
if part == 'passed' and i > 0:
|
|
100
|
-
try:
|
|
101
|
-
results['passed'] = int(parts[i-1])
|
|
102
|
-
except ValueError:
|
|
103
|
-
pass
|
|
104
|
-
if part == 'failed' and i > 0:
|
|
105
|
-
try:
|
|
106
|
-
results['failed'] = int(parts[i-1])
|
|
107
|
-
except ValueError:
|
|
108
|
-
pass
|
|
109
|
-
|
|
110
|
-
# Parse duration
|
|
111
|
-
if 'Duration' in line or 'Time' in line:
|
|
112
|
-
# Try to extract duration
|
|
113
|
-
pass
|
|
114
|
-
|
|
115
|
-
# Collect error messages
|
|
116
|
-
if 'FAIL' in line or 'Error' in line:
|
|
117
|
-
results['errors'].append(line.strip())
|
|
118
|
-
|
|
119
|
-
results['total'] = results['passed'] + results['failed'] + results['skipped']
|
|
120
|
-
|
|
121
|
-
return results
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def format_summary(code: int, results: Dict[str, Any], output: str) -> str:
|
|
125
|
-
"""Format test results into a readable summary."""
|
|
126
|
-
summary = []
|
|
127
|
-
summary.append("=" * 60)
|
|
128
|
-
summary.append("VITEST TEST RESULTS")
|
|
129
|
-
summary.append("=" * 60)
|
|
130
|
-
|
|
131
|
-
if code == 0:
|
|
132
|
-
summary.append("✅ All tests passed!")
|
|
133
|
-
else:
|
|
134
|
-
summary.append("❌ Some tests failed")
|
|
135
|
-
|
|
136
|
-
summary.append("")
|
|
137
|
-
summary.append("Statistics:")
|
|
138
|
-
summary.append(f" Total: {results['total']}")
|
|
139
|
-
summary.append(f" Passed: {results['passed']} ✅")
|
|
140
|
-
summary.append(f" Failed: {results['failed']} ❌")
|
|
141
|
-
summary.append(f" Skipped: {results['skipped']} ⏭️")
|
|
142
|
-
|
|
143
|
-
if results['errors']:
|
|
144
|
-
summary.append("")
|
|
145
|
-
summary.append("Errors/Failures:")
|
|
146
|
-
for error in results['errors'][:10]: # Limit to first 10 errors
|
|
147
|
-
summary.append(f" • {error}")
|
|
148
|
-
|
|
149
|
-
if len(results['errors']) > 10:
|
|
150
|
-
summary.append(f" ... and {len(results['errors']) - 10} more")
|
|
151
|
-
|
|
152
|
-
summary.append("")
|
|
153
|
-
summary.append("=" * 60)
|
|
154
|
-
|
|
155
|
-
return "\n".join(summary)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def main():
|
|
159
|
-
if len(sys.argv) < 2:
|
|
160
|
-
print("Usage: python vitest_runner.py <project_path> [--coverage] [--watch]")
|
|
161
|
-
sys.exit(1)
|
|
162
|
-
|
|
163
|
-
project_path = sys.argv[1]
|
|
164
|
-
coverage = "--coverage" in sys.argv
|
|
165
|
-
watch = "--watch" in sys.argv
|
|
166
|
-
|
|
167
|
-
print("🧪 Vitest Test Runner")
|
|
168
|
-
print("=" * 60)
|
|
169
|
-
print(f"Project: {project_path}")
|
|
170
|
-
print(f"Coverage: {coverage}")
|
|
171
|
-
print(f"Watch mode: {watch}")
|
|
172
|
-
print()
|
|
173
|
-
|
|
174
|
-
# Check if Vitest is installed
|
|
175
|
-
installed, message = check_vitest_installed(project_path)
|
|
176
|
-
if not installed:
|
|
177
|
-
print(f"❌ Error: {message}")
|
|
178
|
-
print("\nTo install Vitest:")
|
|
179
|
-
print(" npm install -D vitest @vue/test-utils")
|
|
180
|
-
sys.exit(1)
|
|
181
|
-
|
|
182
|
-
print(f"✅ {message}")
|
|
183
|
-
print()
|
|
184
|
-
|
|
185
|
-
# Run tests
|
|
186
|
-
print("Running tests...")
|
|
187
|
-
print("-" * 60)
|
|
188
|
-
code, output, results = run_vitest(project_path, coverage, watch)
|
|
189
|
-
|
|
190
|
-
# Print full output
|
|
191
|
-
print(output)
|
|
192
|
-
print()
|
|
193
|
-
|
|
194
|
-
# Print summary
|
|
195
|
-
summary = format_summary(code, results, output)
|
|
196
|
-
print(summary)
|
|
197
|
-
|
|
198
|
-
# Exit with test result code
|
|
199
|
-
sys.exit(code)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if __name__ == "__main__":
|
|
203
|
-
main()
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
xUnit Runner - Backend test execution and validation
|
|
4
|
-
Used by backend-specialist agent to run and validate ASP.NET/C# tests.
|
|
5
|
-
|
|
6
|
-
Usage:
|
|
7
|
-
python xunit_runner.py <project_path>
|
|
8
|
-
python xunit_runner.py <project_path> --coverage
|
|
9
|
-
python xunit_runner.py <project_path> --filter "TestName"
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import subprocess
|
|
13
|
-
import sys
|
|
14
|
-
import re
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Tuple, Dict, Any
|
|
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 check_dotnet_installed() -> Tuple[bool, str]:
|
|
37
|
-
"""Check if .NET SDK is installed."""
|
|
38
|
-
code, output = run_command(["dotnet", "--version"])
|
|
39
|
-
if code == 0:
|
|
40
|
-
version = output.strip()
|
|
41
|
-
return True, f".NET SDK {version} installed"
|
|
42
|
-
return False, "dotnet command not found"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def find_test_projects(project_path: str) -> list[Path]:
|
|
46
|
-
"""Find all test projects (*.Tests.csproj or *Tests.csproj)."""
|
|
47
|
-
path = Path(project_path)
|
|
48
|
-
test_projects = []
|
|
49
|
-
|
|
50
|
-
# Common test project patterns
|
|
51
|
-
patterns = ["*.Tests.csproj", "*Tests.csproj", "*.Test.csproj", "*Test.csproj"]
|
|
52
|
-
|
|
53
|
-
for pattern in patterns:
|
|
54
|
-
test_projects.extend(path.glob(f"**/{pattern}"))
|
|
55
|
-
|
|
56
|
-
# Remove duplicates
|
|
57
|
-
return list(set(test_projects))
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def run_dotnet_test(project_path: str, coverage: bool = False, filter_expr: str = None) -> Tuple[int, str, Dict[str, Any]]:
|
|
61
|
-
"""Run dotnet test and return results."""
|
|
62
|
-
cmd = ["dotnet", "test"]
|
|
63
|
-
|
|
64
|
-
# Add verbosity
|
|
65
|
-
cmd.extend(["--verbosity", "normal"])
|
|
66
|
-
|
|
67
|
-
# Add filter if specified
|
|
68
|
-
if filter_expr:
|
|
69
|
-
cmd.extend(["--filter", filter_expr])
|
|
70
|
-
|
|
71
|
-
# Add coverage if requested
|
|
72
|
-
if coverage:
|
|
73
|
-
cmd.extend(["--collect:XPlat Code Coverage"])
|
|
74
|
-
|
|
75
|
-
code, output = run_command(cmd, project_path)
|
|
76
|
-
|
|
77
|
-
# Parse test results
|
|
78
|
-
results = parse_dotnet_test_output(output)
|
|
79
|
-
|
|
80
|
-
return code, output, results
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def parse_dotnet_test_output(output: str) -> Dict[str, Any]:
|
|
84
|
-
"""Parse dotnet test output to extract test statistics."""
|
|
85
|
-
results = {
|
|
86
|
-
'total': 0,
|
|
87
|
-
'passed': 0,
|
|
88
|
-
'failed': 0,
|
|
89
|
-
'skipped': 0,
|
|
90
|
-
'duration': None,
|
|
91
|
-
'errors': []
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
lines = output.split('\n')
|
|
95
|
-
|
|
96
|
-
for line in lines:
|
|
97
|
-
# Parse test summary line
|
|
98
|
-
# Example: "Passed! - Failed: 0, Passed: 10, Skipped: 0, Total: 10"
|
|
99
|
-
if 'Failed:' in line and 'Passed:' in line and 'Total:' in line:
|
|
100
|
-
# Extract numbers using regex
|
|
101
|
-
failed_match = re.search(r'Failed:\s*(\d+)', line)
|
|
102
|
-
passed_match = re.search(r'Passed:\s*(\d+)', line)
|
|
103
|
-
skipped_match = re.search(r'Skipped:\s*(\d+)', line)
|
|
104
|
-
total_match = re.search(r'Total:\s*(\d+)', line)
|
|
105
|
-
|
|
106
|
-
if failed_match:
|
|
107
|
-
results['failed'] = int(failed_match.group(1))
|
|
108
|
-
if passed_match:
|
|
109
|
-
results['passed'] = int(passed_match.group(1))
|
|
110
|
-
if skipped_match:
|
|
111
|
-
results['skipped'] = int(skipped_match.group(1))
|
|
112
|
-
if total_match:
|
|
113
|
-
results['total'] = int(total_match.group(1))
|
|
114
|
-
|
|
115
|
-
# Parse duration
|
|
116
|
-
# Example: "Time: 00:00:01.23"
|
|
117
|
-
if 'Time:' in line:
|
|
118
|
-
time_match = re.search(r'Time:\s*([\d:\.]+)', line)
|
|
119
|
-
if time_match:
|
|
120
|
-
results['duration'] = time_match.group(1)
|
|
121
|
-
|
|
122
|
-
# Collect error messages
|
|
123
|
-
if 'Failed' in line and '[FAIL]' in line:
|
|
124
|
-
results['errors'].append(line.strip())
|
|
125
|
-
elif 'Error Message:' in line:
|
|
126
|
-
results['errors'].append(line.strip())
|
|
127
|
-
|
|
128
|
-
return results
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def format_summary(code: int, results: Dict[str, Any], test_projects: list[Path]) -> str:
|
|
132
|
-
"""Format test results into a readable summary."""
|
|
133
|
-
summary = []
|
|
134
|
-
summary.append("=" * 60)
|
|
135
|
-
summary.append("XUNIT TEST RESULTS")
|
|
136
|
-
summary.append("=" * 60)
|
|
137
|
-
|
|
138
|
-
if code == 0:
|
|
139
|
-
summary.append("✅ All tests passed!")
|
|
140
|
-
else:
|
|
141
|
-
summary.append("❌ Some tests failed")
|
|
142
|
-
|
|
143
|
-
summary.append("")
|
|
144
|
-
summary.append(f"Test Projects Found: {len(test_projects)}")
|
|
145
|
-
for proj in test_projects:
|
|
146
|
-
summary.append(f" • {proj.name}")
|
|
147
|
-
|
|
148
|
-
summary.append("")
|
|
149
|
-
summary.append("Statistics:")
|
|
150
|
-
summary.append(f" Total: {results['total']}")
|
|
151
|
-
summary.append(f" Passed: {results['passed']} ✅")
|
|
152
|
-
summary.append(f" Failed: {results['failed']} ❌")
|
|
153
|
-
summary.append(f" Skipped: {results['skipped']} ⏭️")
|
|
154
|
-
|
|
155
|
-
if results['duration']:
|
|
156
|
-
summary.append(f" Duration: {results['duration']}")
|
|
157
|
-
|
|
158
|
-
if results['errors']:
|
|
159
|
-
summary.append("")
|
|
160
|
-
summary.append("Errors/Failures:")
|
|
161
|
-
for error in results['errors'][:10]: # Limit to first 10 errors
|
|
162
|
-
summary.append(f" • {error}")
|
|
163
|
-
|
|
164
|
-
if len(results['errors']) > 10:
|
|
165
|
-
summary.append(f" ... and {len(results['errors']) - 10} more")
|
|
166
|
-
|
|
167
|
-
summary.append("")
|
|
168
|
-
summary.append("=" * 60)
|
|
169
|
-
|
|
170
|
-
return "\n".join(summary)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
def main():
|
|
174
|
-
if len(sys.argv) < 2:
|
|
175
|
-
print("Usage: python xunit_runner.py <project_path> [--coverage] [--filter <expression>]")
|
|
176
|
-
sys.exit(1)
|
|
177
|
-
|
|
178
|
-
project_path = sys.argv[1]
|
|
179
|
-
coverage = "--coverage" in sys.argv
|
|
180
|
-
filter_expr = None
|
|
181
|
-
|
|
182
|
-
if "--filter" in sys.argv:
|
|
183
|
-
filter_index = sys.argv.index("--filter") + 1
|
|
184
|
-
if filter_index < len(sys.argv):
|
|
185
|
-
filter_expr = sys.argv[filter_index]
|
|
186
|
-
|
|
187
|
-
print("🧪 xUnit Test Runner")
|
|
188
|
-
print("=" * 60)
|
|
189
|
-
print(f"Project: {project_path}")
|
|
190
|
-
print(f"Coverage: {coverage}")
|
|
191
|
-
if filter_expr:
|
|
192
|
-
print(f"Filter: {filter_expr}")
|
|
193
|
-
print()
|
|
194
|
-
|
|
195
|
-
# Check if .NET is installed
|
|
196
|
-
installed, message = check_dotnet_installed()
|
|
197
|
-
if not installed:
|
|
198
|
-
print(f"❌ Error: {message}")
|
|
199
|
-
print("\nPlease install .NET SDK from: https://dotnet.microsoft.com/download")
|
|
200
|
-
sys.exit(1)
|
|
201
|
-
|
|
202
|
-
print(f"✅ {message}")
|
|
203
|
-
|
|
204
|
-
# Find test projects
|
|
205
|
-
test_projects = find_test_projects(project_path)
|
|
206
|
-
if not test_projects:
|
|
207
|
-
print("⚠️ No test projects found")
|
|
208
|
-
print("\nTest projects should match patterns:")
|
|
209
|
-
print(" • *.Tests.csproj")
|
|
210
|
-
print(" • *Tests.csproj")
|
|
211
|
-
print(" • *.Test.csproj")
|
|
212
|
-
sys.exit(1)
|
|
213
|
-
|
|
214
|
-
print(f"✅ Found {len(test_projects)} test project(s)")
|
|
215
|
-
print()
|
|
216
|
-
|
|
217
|
-
# Run tests
|
|
218
|
-
print("Running tests...")
|
|
219
|
-
print("-" * 60)
|
|
220
|
-
code, output, results = run_dotnet_test(project_path, coverage, filter_expr)
|
|
221
|
-
|
|
222
|
-
# Print full output
|
|
223
|
-
print(output)
|
|
224
|
-
print()
|
|
225
|
-
|
|
226
|
-
# Print summary
|
|
227
|
-
summary = format_summary(code, results, test_projects)
|
|
228
|
-
print(summary)
|
|
229
|
-
|
|
230
|
-
# Exit with test result code
|
|
231
|
-
sys.exit(code)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if __name__ == "__main__":
|
|
235
|
-
main()
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: api-patterns
|
|
3
|
-
description: REST API design patterns and best practices
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# API Patterns
|
|
7
|
-
|
|
8
|
-
> RESTful API design for ASP.NET Core.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## REST Conventions
|
|
13
|
-
|
|
14
|
-
| Method | Action | Route | Response |
|
|
15
|
-
|--------|--------|-------|----------|
|
|
16
|
-
| GET | List | /api/users | 200 + array |
|
|
17
|
-
| GET | Read | /api/users/{id} | 200 or 404 |
|
|
18
|
-
| POST | Create | /api/users | 201 + object |
|
|
19
|
-
| PUT | Update | /api/users/{id} | 200 or 404 |
|
|
20
|
-
| DELETE | Delete | /api/users/{id} | 204 or 404 |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Response Format
|
|
25
|
-
|
|
26
|
-
```csharp
|
|
27
|
-
public class ApiResponse<T>
|
|
28
|
-
{
|
|
29
|
-
public bool Success { get; set; }
|
|
30
|
-
public T? Data { get; set; }
|
|
31
|
-
public string? Error { get; set; }
|
|
32
|
-
public List<string>? Errors { get; set; }
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Pagination
|
|
39
|
-
|
|
40
|
-
```csharp
|
|
41
|
-
[HttpGet]
|
|
42
|
-
public async Task<ActionResult<PagedResult<UserDto>>> GetUsers(
|
|
43
|
-
[FromQuery] int page = 1,
|
|
44
|
-
[FromQuery] int pageSize = 20)
|
|
45
|
-
{
|
|
46
|
-
var result = await _service.GetPagedAsync(page, pageSize);
|
|
47
|
-
return Ok(result);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public class PagedResult<T>
|
|
51
|
-
{
|
|
52
|
-
public List<T> Items { get; set; }
|
|
53
|
-
public int TotalCount { get; set; }
|
|
54
|
-
public int Page { get; set; }
|
|
55
|
-
public int PageSize { get; set; }
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Validation
|
|
62
|
-
|
|
63
|
-
```csharp
|
|
64
|
-
public class CreateUserDto
|
|
65
|
-
{
|
|
66
|
-
[Required]
|
|
67
|
-
[EmailAddress]
|
|
68
|
-
public string Email { get; set; }
|
|
69
|
-
|
|
70
|
-
[Required]
|
|
71
|
-
[StringLength(100, MinimumLength = 2)]
|
|
72
|
-
public string Name { get; set; }
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Error Handling
|
|
79
|
-
|
|
80
|
-
```csharp
|
|
81
|
-
// Global exception handler
|
|
82
|
-
app.UseExceptionHandler(app =>
|
|
83
|
-
{
|
|
84
|
-
app.Run(async context =>
|
|
85
|
-
{
|
|
86
|
-
context.Response.StatusCode = 500;
|
|
87
|
-
await context.Response.WriteAsJsonAsync(new ApiResponse<object>
|
|
88
|
-
{
|
|
89
|
-
Success = false,
|
|
90
|
-
Error = "An error occurred"
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Versioning
|
|
99
|
-
|
|
100
|
-
```csharp
|
|
101
|
-
[ApiController]
|
|
102
|
-
[Route("api/v{version:apiVersion}/[controller]")]
|
|
103
|
-
[ApiVersion("1.0")]
|
|
104
|
-
public class UsersController : ControllerBase
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## DO / DON'T
|
|
110
|
-
|
|
111
|
-
| ✅ Do | ❌ Don't |
|
|
112
|
-
|-------|---------|
|
|
113
|
-
| Consistent responses | Mixed formats |
|
|
114
|
-
| Proper status codes | 200 for everything |
|
|
115
|
-
| Validate input | Trust user data |
|
|
116
|
-
| Version APIs | Breaking changes |
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: architecture
|
|
3
|
-
description: System design patterns and architecture decisions
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Architecture Patterns
|
|
7
|
-
|
|
8
|
-
> System design for Vue3 + ASP.NET applications.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Layered Architecture
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
┌─────────────────────────────────────┐
|
|
16
|
-
│ Presentation (Vue3) │
|
|
17
|
-
├─────────────────────────────────────┤
|
|
18
|
-
│ API (Controllers) │
|
|
19
|
-
├─────────────────────────────────────┤
|
|
20
|
-
│ Business Logic (Services) │
|
|
21
|
-
├─────────────────────────────────────┤
|
|
22
|
-
│ Data Access (Repositories) │
|
|
23
|
-
├─────────────────────────────────────┤
|
|
24
|
-
│ Database (SQL Server) │
|
|
25
|
-
└─────────────────────────────────────┘
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Frontend Architecture
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
src/
|
|
34
|
-
├── components/ # Reusable UI components
|
|
35
|
-
├── composables/ # Shared logic (useXxx)
|
|
36
|
-
├── views/ # Page components
|
|
37
|
-
├── stores/ # Pinia stores
|
|
38
|
-
├── api/ # API client
|
|
39
|
-
├── types/ # TypeScript types
|
|
40
|
-
└── router/ # Vue Router
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Backend Architecture
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
src/
|
|
49
|
-
├── Controllers/ # HTTP endpoints
|
|
50
|
-
├── Services/ # Business logic
|
|
51
|
-
├── Repositories/ # Data access
|
|
52
|
-
├── Models/ # Domain models
|
|
53
|
-
├── DTOs/ # Data transfer objects
|
|
54
|
-
└── Infrastructure/ # Cross-cutting concerns
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Communication Patterns
|
|
60
|
-
|
|
61
|
-
| Pattern | Use Case |
|
|
62
|
-
|---------|----------|
|
|
63
|
-
| REST API | Standard CRUD operations |
|
|
64
|
-
| SignalR | Real-time updates |
|
|
65
|
-
| Background Jobs | Async processing |
|
|
66
|
-
| Message Queue | Event-driven systems |
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Decision Matrix
|
|
71
|
-
|
|
72
|
-
| Decision | Option A | Option B |
|
|
73
|
-
|----------|----------|----------|
|
|
74
|
-
| State management | Pinia | Composables |
|
|
75
|
-
| API calls | Axios | Fetch |
|
|
76
|
-
| Forms | VeeValidate | Native |
|
|
77
|
-
| Testing | Vitest | Jest |
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Scaling Considerations
|
|
82
|
-
|
|
83
|
-
| Layer | Strategy |
|
|
84
|
-
|-------|----------|
|
|
85
|
-
| Frontend | CDN, code splitting |
|
|
86
|
-
| API | Horizontal scaling, load balancer |
|
|
87
|
-
| Database | Read replicas, caching |
|
|
88
|
-
| Background | Worker processes |
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## DO / DON'T
|
|
93
|
-
|
|
94
|
-
| ✅ Do | ❌ Don't |
|
|
95
|
-
|-------|---------|
|
|
96
|
-
| Clear layer separation | Mixed concerns |
|
|
97
|
-
| Dependency injection | Hard dependencies |
|
|
98
|
-
| Interface-based design | Concrete dependencies |
|