@girardelli/architect 1.3.0 → 2.2.0
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 +111 -112
- package/dist/agent-generator.d.ts +106 -0
- package/dist/agent-generator.d.ts.map +1 -0
- package/dist/agent-generator.js +1398 -0
- package/dist/agent-generator.js.map +1 -0
- package/dist/cli.js +132 -15
- package/dist/cli.js.map +1 -1
- package/dist/html-reporter.d.ts +8 -2
- package/dist/html-reporter.d.ts.map +1 -1
- package/dist/html-reporter.js +773 -50
- package/dist/html-reporter.js.map +1 -1
- package/dist/index.d.ts +26 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/refactor-engine.d.ts +18 -0
- package/dist/refactor-engine.d.ts.map +1 -0
- package/dist/refactor-engine.js +86 -0
- package/dist/refactor-engine.js.map +1 -0
- package/dist/refactor-reporter.d.ts +20 -0
- package/dist/refactor-reporter.d.ts.map +1 -0
- package/dist/refactor-reporter.js +389 -0
- package/dist/refactor-reporter.js.map +1 -0
- package/dist/rules/barrel-optimizer.d.ts +13 -0
- package/dist/rules/barrel-optimizer.d.ts.map +1 -0
- package/dist/rules/barrel-optimizer.js +77 -0
- package/dist/rules/barrel-optimizer.js.map +1 -0
- package/dist/rules/dead-code-detector.d.ts +21 -0
- package/dist/rules/dead-code-detector.d.ts.map +1 -0
- package/dist/rules/dead-code-detector.js +117 -0
- package/dist/rules/dead-code-detector.js.map +1 -0
- package/dist/rules/hub-splitter.d.ts +13 -0
- package/dist/rules/hub-splitter.d.ts.map +1 -0
- package/dist/rules/hub-splitter.js +110 -0
- package/dist/rules/hub-splitter.js.map +1 -0
- package/dist/rules/import-organizer.d.ts +13 -0
- package/dist/rules/import-organizer.d.ts.map +1 -0
- package/dist/rules/import-organizer.js +85 -0
- package/dist/rules/import-organizer.js.map +1 -0
- package/dist/rules/module-grouper.d.ts +13 -0
- package/dist/rules/module-grouper.d.ts.map +1 -0
- package/dist/rules/module-grouper.js +110 -0
- package/dist/rules/module-grouper.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agent-generator.ts +1526 -0
- package/src/cli.ts +150 -15
- package/src/html-reporter.ts +799 -51
- package/src/index.ts +39 -1
- package/src/refactor-engine.ts +117 -0
- package/src/refactor-reporter.ts +408 -0
- package/src/rules/barrel-optimizer.ts +97 -0
- package/src/rules/dead-code-detector.ts +132 -0
- package/src/rules/hub-splitter.ts +123 -0
- package/src/rules/import-organizer.ts +98 -0
- package/src/rules/module-grouper.ts +124 -0
- package/src/types.ts +52 -0
|
@@ -0,0 +1,1398 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, statSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Agent Generator — Creates or audits .agent/ directories
|
|
5
|
+
* customized to the analyzed project's stack and architecture.
|
|
6
|
+
*/
|
|
7
|
+
export class AgentGenerator {
|
|
8
|
+
/**
|
|
9
|
+
* Suggest agents without writing files — for unified report.
|
|
10
|
+
*/
|
|
11
|
+
suggest(report, plan, projectPath) {
|
|
12
|
+
this.report = report;
|
|
13
|
+
this.plan = plan;
|
|
14
|
+
this.stack = this.detectStack(report);
|
|
15
|
+
const agentDir = join(projectPath, '.agent');
|
|
16
|
+
const isExisting = existsSync(agentDir);
|
|
17
|
+
// Helper: scan existing files in a subdirectory
|
|
18
|
+
const existingFiles = (subdir) => {
|
|
19
|
+
const dir = join(agentDir, subdir);
|
|
20
|
+
if (!existsSync(dir))
|
|
21
|
+
return new Set();
|
|
22
|
+
return new Set(readdirSync(dir).map(f => f.replace(/\.md$/, '')));
|
|
23
|
+
};
|
|
24
|
+
// Helper: determine status for an item
|
|
25
|
+
const itemStatus = (name, existingSet, auditFindings) => {
|
|
26
|
+
// Check if a matching file exists (case-insensitive comparison)
|
|
27
|
+
const found = [...existingSet].some(e => e.toLowerCase() === name.toLowerCase());
|
|
28
|
+
if (!found)
|
|
29
|
+
return 'CREATE';
|
|
30
|
+
// Exists — check if audit flagged it for improvement
|
|
31
|
+
const hasImprovement = auditFindings.some(f => f.file.toLowerCase().includes(name.toLowerCase()) && (f.type === 'IMPROVEMENT' || f.type === 'OUTDATED'));
|
|
32
|
+
return hasImprovement ? 'MODIFY' : 'KEEP';
|
|
33
|
+
};
|
|
34
|
+
// Build suggested agents with descriptions
|
|
35
|
+
const agentDefs = [
|
|
36
|
+
{ name: 'AGENT-ORCHESTRATOR', desc: 'Coordena todos os agentes, decompõe requisições e consolida entregas' },
|
|
37
|
+
];
|
|
38
|
+
if (this.stack.hasBackend)
|
|
39
|
+
agentDefs.push({
|
|
40
|
+
name: `${this.stack.primary.toUpperCase()}-BACKEND-DEVELOPER`,
|
|
41
|
+
desc: `Especialista em arquitetura ${this.stack.primary}, APIs, serviços e lógica de negócio`,
|
|
42
|
+
});
|
|
43
|
+
if (this.stack.hasFrontend) {
|
|
44
|
+
const fw = this.stack.frameworks.find(f => ['Angular', 'Vue', 'Next.js', 'React'].includes(f)) || 'FRONTEND';
|
|
45
|
+
agentDefs.push({
|
|
46
|
+
name: `${fw.toUpperCase().replace('.', '')}-FRONTEND-DEVELOPER`,
|
|
47
|
+
desc: `Desenvolve componentes ${fw}, gerencia estado e garante UX responsiva`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (this.stack.hasMobile)
|
|
51
|
+
agentDefs.push({
|
|
52
|
+
name: 'FLUTTER-UI-DEVELOPER',
|
|
53
|
+
desc: 'Screens mobile, widgets, navegação e integração com APIs',
|
|
54
|
+
});
|
|
55
|
+
if (this.stack.hasDatabase)
|
|
56
|
+
agentDefs.push({
|
|
57
|
+
name: 'DATABASE-ENGINEER',
|
|
58
|
+
desc: 'Schema design, migrations, indexação e performance de queries',
|
|
59
|
+
});
|
|
60
|
+
agentDefs.push({ name: 'SECURITY-AUDITOR', desc: 'Análise de ameaças, compliance LGPD/OWASP e prevenção de vulnerabilidades' }, { name: 'QA-TEST-ENGINEER', desc: 'Planos de teste, cobertura mínima, BDD/TDD e testes de regressão' }, { name: 'TECH-DEBT-CONTROLLER', desc: 'Controle de débito técnico, priorização de refatorações e metas de score' });
|
|
61
|
+
const ruleDefs = [
|
|
62
|
+
{ name: '00-general', desc: 'Convenções de código, nomenclatura, commits e princípios gerais' },
|
|
63
|
+
{ name: '01-architecture', desc: 'Separação de camadas, dependency rules e padrões de módulo' },
|
|
64
|
+
{ name: '02-security', desc: 'Sanitização de inputs, secrets management e validação de dados' },
|
|
65
|
+
];
|
|
66
|
+
if (this.stack.hasBackend)
|
|
67
|
+
ruleDefs.push({
|
|
68
|
+
name: `03-${this.stack.primary.toLowerCase()}`,
|
|
69
|
+
desc: `Padrões específicos de ${this.stack.primary}: framework conventions e anti-patterns`,
|
|
70
|
+
});
|
|
71
|
+
const guardDefs = [
|
|
72
|
+
{ name: 'PREFLIGHT', desc: 'Checklist pré-ação: branch, build, testes antes de qualquer mudança' },
|
|
73
|
+
{ name: 'QUALITY-GATES', desc: 'Score mínimo, cobertura, zero warnings e critérios de merge' },
|
|
74
|
+
{ name: 'CODE-REVIEW-CHECKLIST', desc: 'Pontos obrigatórios de revisão: segurança, performance, legibilidade' },
|
|
75
|
+
];
|
|
76
|
+
const workflowDefs = [
|
|
77
|
+
{ name: 'develop', desc: 'Fluxo completo: branch → mockup → spec → code → test → review → merge' },
|
|
78
|
+
{ name: 'fix-bug', desc: 'Diagnóstico → reprodução → root cause → fix → teste de regressão' },
|
|
79
|
+
{ name: 'review', desc: 'Code review estruturado com checklist de qualidade e segurança' },
|
|
80
|
+
];
|
|
81
|
+
// Run audit first to inform status
|
|
82
|
+
let audit = [];
|
|
83
|
+
if (isExisting) {
|
|
84
|
+
audit = this.auditExisting(agentDir);
|
|
85
|
+
}
|
|
86
|
+
// Get existing files
|
|
87
|
+
const existingAgents = existingFiles('agents');
|
|
88
|
+
const existingRules = existingFiles('rules');
|
|
89
|
+
const existingGuards = existingFiles('guards');
|
|
90
|
+
const existingWorkflows = existingFiles('workflows');
|
|
91
|
+
const existingSkillsDir = join(agentDir, 'skills');
|
|
92
|
+
const existingSkillNames = existsSync(existingSkillsDir)
|
|
93
|
+
? new Set(readdirSync(existingSkillsDir).filter(f => {
|
|
94
|
+
try {
|
|
95
|
+
return statSync(join(existingSkillsDir, f)).isDirectory();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}))
|
|
101
|
+
: new Set();
|
|
102
|
+
// Build items with status and description
|
|
103
|
+
const suggestedAgents = agentDefs.map(({ name, desc }) => ({
|
|
104
|
+
name,
|
|
105
|
+
status: itemStatus(name, existingAgents, audit),
|
|
106
|
+
description: desc,
|
|
107
|
+
}));
|
|
108
|
+
// Detect files that exist but are NOT suggested → KEEP (custom)
|
|
109
|
+
for (const existing of existingAgents) {
|
|
110
|
+
if (!agentDefs.some(d => d.name.toLowerCase() === existing.toLowerCase())) {
|
|
111
|
+
suggestedAgents.push({ name: existing, status: 'KEEP', reason: 'Custom agent', description: 'Agente customizado do projeto' });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const suggestedRules = ruleDefs.map(({ name, desc }) => ({
|
|
115
|
+
name,
|
|
116
|
+
status: itemStatus(name, existingRules, audit),
|
|
117
|
+
description: desc,
|
|
118
|
+
}));
|
|
119
|
+
for (const existing of existingRules) {
|
|
120
|
+
if (!ruleDefs.some(d => d.name.toLowerCase() === existing.toLowerCase())) {
|
|
121
|
+
suggestedRules.push({ name: existing, status: 'KEEP', reason: 'Custom rule', description: 'Regra customizada do projeto' });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const suggestedGuards = guardDefs.map(({ name, desc }) => ({
|
|
125
|
+
name,
|
|
126
|
+
status: itemStatus(name, existingGuards, audit),
|
|
127
|
+
description: desc,
|
|
128
|
+
}));
|
|
129
|
+
const suggestedWorkflows = workflowDefs.map(({ name, desc }) => ({
|
|
130
|
+
name,
|
|
131
|
+
status: itemStatus(name, existingWorkflows, audit),
|
|
132
|
+
description: desc,
|
|
133
|
+
}));
|
|
134
|
+
for (const existing of existingWorkflows) {
|
|
135
|
+
if (!workflowDefs.some(d => d.name.toLowerCase() === existing.toLowerCase())) {
|
|
136
|
+
suggestedWorkflows.push({ name: existing, status: 'KEEP', reason: 'Custom workflow', description: 'Workflow customizado do projeto' });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Skills
|
|
140
|
+
const skillEntries = [
|
|
141
|
+
{ name: 'test-driven-development', source: 'anthropic/courses/test-driven-development', description: 'TDD workflow: Red → Green → Refactor', status: 'CREATE' },
|
|
142
|
+
{ name: 'systematic-debugging', source: 'anthropic/courses/systematic-debugging', description: 'Structured debugging methodology', status: 'CREATE' },
|
|
143
|
+
{ name: 'code-review', source: 'anthropic/courses/requesting-code-review', description: 'Code review best practices', status: 'CREATE' },
|
|
144
|
+
{ name: 'security-best-practices', source: 'anthropic/courses/security-best-practices', description: 'Security patterns and vulnerability prevention', status: 'CREATE' },
|
|
145
|
+
{ name: 'performance-optimization', source: 'anthropic/courses/performance-optimization', description: 'Performance analysis and optimization', status: 'CREATE' },
|
|
146
|
+
{ name: 'git-workflow', source: 'anthropic/courses/git-workflow', description: 'Git branching, commits, and collaboration', status: 'CREATE' },
|
|
147
|
+
];
|
|
148
|
+
if (this.stack.languages.includes('TypeScript') || this.stack.languages.includes('JavaScript')) {
|
|
149
|
+
skillEntries.push({ name: 'next-best-practices', source: 'vercel-labs/skills/next-best-practices', description: 'Next.js patterns and performance', status: 'CREATE' }, { name: 'api-design-principles', source: 'anthropic/courses/api-design-principles', description: 'REST/GraphQL API design', status: 'CREATE' });
|
|
150
|
+
}
|
|
151
|
+
if (this.stack.frameworks.includes('Angular') || this.stack.frameworks.includes('Vue') || this.stack.frameworks.includes('React') || this.stack.frameworks.includes('Next.js')) {
|
|
152
|
+
skillEntries.push({ name: 'frontend-design', source: 'anthropic/courses/frontend-design', description: 'Modern frontend patterns and UI/UX', status: 'CREATE' }, { name: 'web-accessibility', source: 'anthropic/courses/web-accessibility', description: 'WCAG accessibility standards', status: 'CREATE' }, { name: 'ui-ux-pro-max', source: 'anthropic/courses/ui-ux-pro-max', description: '50 styles, 21 palettes, 50 font pairings', status: 'CREATE' });
|
|
153
|
+
}
|
|
154
|
+
if (this.stack.frameworks.includes('Vue')) {
|
|
155
|
+
skillEntries.push({ name: 'vue-best-practices', source: 'anthropic/courses/vue-best-practices', description: 'Vue.js composition API and patterns', status: 'CREATE' });
|
|
156
|
+
}
|
|
157
|
+
if (this.stack.languages.includes('Dart') || this.stack.frameworks.includes('Flutter')) {
|
|
158
|
+
skillEntries.push({ name: 'flutter-animations', source: 'anthropic/courses/flutter-animations', description: 'Flutter animation patterns', status: 'CREATE' });
|
|
159
|
+
}
|
|
160
|
+
if (this.stack.languages.includes('Python')) {
|
|
161
|
+
skillEntries.push({ name: 'python-performance', source: 'anthropic/courses/python-performance-optimization', description: 'Python optimization and profiling', status: 'CREATE' });
|
|
162
|
+
}
|
|
163
|
+
if (this.stack.hasDatabase) {
|
|
164
|
+
skillEntries.push({ name: 'database-schema-design', source: 'anthropic/courses/database-schema-design', description: 'Schema design, indexing, migrations', status: 'CREATE' });
|
|
165
|
+
}
|
|
166
|
+
// Update skill status based on existing skills directory
|
|
167
|
+
for (const skill of skillEntries) {
|
|
168
|
+
if (existingSkillNames.has(skill.name)) {
|
|
169
|
+
skill.status = 'KEEP';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
stack: this.stack,
|
|
174
|
+
hasExistingAgents: isExisting,
|
|
175
|
+
suggestedAgents,
|
|
176
|
+
suggestedRules,
|
|
177
|
+
suggestedGuards,
|
|
178
|
+
suggestedWorkflows,
|
|
179
|
+
suggestedSkills: skillEntries,
|
|
180
|
+
audit,
|
|
181
|
+
command: `architect agents ${projectPath}`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Main entry: generate or audit .agent/ for a project.
|
|
186
|
+
*/
|
|
187
|
+
generate(report, plan, projectPath, outputDir) {
|
|
188
|
+
this.report = report;
|
|
189
|
+
this.plan = plan;
|
|
190
|
+
this.stack = this.detectStack(report);
|
|
191
|
+
const agentDir = outputDir || join(projectPath, '.agent');
|
|
192
|
+
const isExisting = existsSync(agentDir);
|
|
193
|
+
if (isExisting) {
|
|
194
|
+
const audit = this.auditExisting(agentDir);
|
|
195
|
+
const generated = this.generateMissing(agentDir, audit);
|
|
196
|
+
return { generated, audit };
|
|
197
|
+
}
|
|
198
|
+
const generated = this.generateFull(agentDir);
|
|
199
|
+
return { generated, audit: [] };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Detect technology stack from the analysis report.
|
|
203
|
+
*/
|
|
204
|
+
detectStack(report) {
|
|
205
|
+
const files = report.dependencyGraph.nodes;
|
|
206
|
+
const extensions = new Set();
|
|
207
|
+
const languages = new Set();
|
|
208
|
+
const frameworks = new Set();
|
|
209
|
+
for (const file of files) {
|
|
210
|
+
const ext = file.split('.').pop()?.toLowerCase() || '';
|
|
211
|
+
extensions.add(ext);
|
|
212
|
+
}
|
|
213
|
+
// Detect languages
|
|
214
|
+
if (extensions.has('py'))
|
|
215
|
+
languages.add('Python');
|
|
216
|
+
if (extensions.has('ts') || extensions.has('tsx'))
|
|
217
|
+
languages.add('TypeScript');
|
|
218
|
+
if (extensions.has('js') || extensions.has('jsx'))
|
|
219
|
+
languages.add('JavaScript');
|
|
220
|
+
if (extensions.has('dart'))
|
|
221
|
+
languages.add('Dart');
|
|
222
|
+
if (extensions.has('go'))
|
|
223
|
+
languages.add('Go');
|
|
224
|
+
if (extensions.has('rs'))
|
|
225
|
+
languages.add('Rust');
|
|
226
|
+
if (extensions.has('java') || extensions.has('kt'))
|
|
227
|
+
languages.add('Java/Kotlin');
|
|
228
|
+
if (extensions.has('rb'))
|
|
229
|
+
languages.add('Ruby');
|
|
230
|
+
if (extensions.has('php'))
|
|
231
|
+
languages.add('PHP');
|
|
232
|
+
if (extensions.has('cs'))
|
|
233
|
+
languages.add('C#');
|
|
234
|
+
// Detect frameworks from file patterns
|
|
235
|
+
const allFiles = files.join(' ');
|
|
236
|
+
if (allFiles.includes('manage.py') || allFiles.includes('django'))
|
|
237
|
+
frameworks.add('Django');
|
|
238
|
+
if (allFiles.includes('flask') || allFiles.includes('app.py'))
|
|
239
|
+
frameworks.add('Flask');
|
|
240
|
+
if (allFiles.includes('fastapi'))
|
|
241
|
+
frameworks.add('FastAPI');
|
|
242
|
+
if (allFiles.includes('.module.ts') || allFiles.includes('nest'))
|
|
243
|
+
frameworks.add('NestJS');
|
|
244
|
+
if (allFiles.includes('.component.ts') || allFiles.includes('angular'))
|
|
245
|
+
frameworks.add('Angular');
|
|
246
|
+
if (allFiles.includes('.vue'))
|
|
247
|
+
frameworks.add('Vue');
|
|
248
|
+
if (allFiles.includes('.tsx') && allFiles.includes('next'))
|
|
249
|
+
frameworks.add('Next.js');
|
|
250
|
+
if (allFiles.includes('.dart'))
|
|
251
|
+
frameworks.add('Flutter');
|
|
252
|
+
if (allFiles.includes('go.mod'))
|
|
253
|
+
frameworks.add('Go Modules');
|
|
254
|
+
if (allFiles.includes('Cargo.toml'))
|
|
255
|
+
frameworks.add('Cargo');
|
|
256
|
+
if (allFiles.includes('pom.xml') || allFiles.includes('build.gradle'))
|
|
257
|
+
frameworks.add('Spring');
|
|
258
|
+
const primary = languages.size > 0 ? [...languages][0] : 'Unknown';
|
|
259
|
+
const hasBackend = languages.has('Python') || languages.has('TypeScript') ||
|
|
260
|
+
languages.has('Go') || languages.has('Java/Kotlin') || languages.has('Ruby') || languages.has('PHP');
|
|
261
|
+
const hasFrontend = frameworks.has('Angular') || frameworks.has('Vue') ||
|
|
262
|
+
frameworks.has('Next.js') || extensions.has('html');
|
|
263
|
+
const hasMobile = languages.has('Dart') || frameworks.has('Flutter');
|
|
264
|
+
const hasDatabase = allFiles.includes('migration') || allFiles.includes('entity') ||
|
|
265
|
+
allFiles.includes('model') || allFiles.includes('schema');
|
|
266
|
+
let testFramework = 'Jest';
|
|
267
|
+
if (languages.has('Python'))
|
|
268
|
+
testFramework = 'pytest';
|
|
269
|
+
if (languages.has('Go'))
|
|
270
|
+
testFramework = 'go test';
|
|
271
|
+
if (languages.has('Dart'))
|
|
272
|
+
testFramework = 'flutter_test';
|
|
273
|
+
let packageManager = 'npm';
|
|
274
|
+
if (languages.has('Python'))
|
|
275
|
+
packageManager = 'pip';
|
|
276
|
+
if (languages.has('Go'))
|
|
277
|
+
packageManager = 'go mod';
|
|
278
|
+
if (languages.has('Dart'))
|
|
279
|
+
packageManager = 'pub';
|
|
280
|
+
return {
|
|
281
|
+
primary, languages: [...languages], frameworks: [...frameworks],
|
|
282
|
+
hasBackend, hasFrontend, hasMobile, hasDatabase,
|
|
283
|
+
testFramework, packageManager,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
// ── Audit Existing ──
|
|
287
|
+
auditExisting(agentDir) {
|
|
288
|
+
const findings = [];
|
|
289
|
+
const checkExists = (subpath, category, desc) => {
|
|
290
|
+
const full = join(agentDir, subpath);
|
|
291
|
+
if (!existsSync(full)) {
|
|
292
|
+
findings.push({ type: 'MISSING', category, file: subpath, description: desc });
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
findings.push({ type: 'OK', category, file: subpath, description: `${subpath} exists` });
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
// Check required structure
|
|
299
|
+
checkExists('INDEX.md', 'core', 'Index file for agent navigation');
|
|
300
|
+
checkExists('agents/AGENT-ORCHESTRATOR.md', 'agents', 'Orchestrator agent');
|
|
301
|
+
checkExists('rules/00-general.md', 'rules', 'General rules');
|
|
302
|
+
checkExists('guards/PREFLIGHT.md', 'guards', 'Preflight checklist');
|
|
303
|
+
checkExists('workflows/develop.md', 'workflows', 'Development workflow');
|
|
304
|
+
// Check stack-specific agents
|
|
305
|
+
if (this.stack.hasBackend) {
|
|
306
|
+
const backendAgent = this.findAgentByRole(agentDir, 'backend');
|
|
307
|
+
if (!backendAgent) {
|
|
308
|
+
findings.push({
|
|
309
|
+
type: 'MISSING', category: 'agents',
|
|
310
|
+
file: `agents/${this.stack.primary.toUpperCase()}-BACKEND-DEVELOPER.md`,
|
|
311
|
+
description: `No backend developer agent for ${this.stack.primary}`,
|
|
312
|
+
suggestion: `Create a ${this.stack.primary} backend agent with patterns, conventions, and architecture rules`,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (this.stack.hasFrontend) {
|
|
317
|
+
const frontAgent = this.findAgentByRole(agentDir, 'frontend');
|
|
318
|
+
if (!frontAgent) {
|
|
319
|
+
findings.push({
|
|
320
|
+
type: 'MISSING', category: 'agents',
|
|
321
|
+
file: 'agents/FRONTEND-DEVELOPER.md',
|
|
322
|
+
description: 'No frontend developer agent',
|
|
323
|
+
suggestion: `Create a frontend agent for ${this.stack.frameworks.join(', ')}`,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Check for tech debt alignment
|
|
328
|
+
if (this.plan.steps.length > 0) {
|
|
329
|
+
const techDebtAgent = this.findAgentByRole(agentDir, 'tech-debt');
|
|
330
|
+
if (!techDebtAgent) {
|
|
331
|
+
findings.push({
|
|
332
|
+
type: 'IMPROVEMENT', category: 'agents',
|
|
333
|
+
file: 'agents/TECH-DEBT-CONTROLLER.md',
|
|
334
|
+
description: `${this.plan.steps.length} refactoring steps found but no Tech Debt agent`,
|
|
335
|
+
suggestion: 'Create a Tech Debt Controller with the refactoring backlog',
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// Check quality gates match score
|
|
340
|
+
if (this.report.score.overall < 80) {
|
|
341
|
+
findings.push({
|
|
342
|
+
type: 'IMPROVEMENT', category: 'guards',
|
|
343
|
+
file: 'guards/QUALITY-GATES.md',
|
|
344
|
+
description: `Score is ${this.report.score.overall}/100 — quality gates should enforce improvement`,
|
|
345
|
+
suggestion: `Set minimum score threshold to ${this.report.score.overall + 5} and add regression guards`,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
// Check anti-pattern rules
|
|
349
|
+
for (const ap of this.report.antiPatterns) {
|
|
350
|
+
findings.push({
|
|
351
|
+
type: 'IMPROVEMENT', category: 'rules',
|
|
352
|
+
file: `rules/anti-pattern-${ap.name.toLowerCase().replace(/\s+/g, '-')}.md`,
|
|
353
|
+
description: `Anti-pattern "${ap.name}" (${ap.severity}) detected but no prevention rule`,
|
|
354
|
+
suggestion: `Add a rule to prevent "${ap.name}" from recurring`,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return findings;
|
|
358
|
+
}
|
|
359
|
+
findAgentByRole(agentDir, role) {
|
|
360
|
+
const agentsDir = join(agentDir, 'agents');
|
|
361
|
+
if (!existsSync(agentsDir))
|
|
362
|
+
return null;
|
|
363
|
+
const files = readdirSync(agentsDir);
|
|
364
|
+
for (const file of files) {
|
|
365
|
+
const content = readFileSync(join(agentsDir, file), 'utf-8').toLowerCase();
|
|
366
|
+
if (content.includes(role))
|
|
367
|
+
return file;
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
generateMissing(agentDir, audit) {
|
|
372
|
+
const generated = [];
|
|
373
|
+
const missing = audit.filter(f => f.type === 'MISSING');
|
|
374
|
+
for (const finding of missing) {
|
|
375
|
+
const fullPath = join(agentDir, finding.file);
|
|
376
|
+
const dir = join(fullPath, '..');
|
|
377
|
+
if (!existsSync(dir))
|
|
378
|
+
mkdirSync(dir, { recursive: true });
|
|
379
|
+
const content = this.getTemplateFor(finding.category, finding.file);
|
|
380
|
+
if (content) {
|
|
381
|
+
writeFileSync(fullPath, content);
|
|
382
|
+
generated.push(finding.file);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return generated;
|
|
386
|
+
}
|
|
387
|
+
// ── Full Generation ──
|
|
388
|
+
generateFull(agentDir) {
|
|
389
|
+
const generated = [];
|
|
390
|
+
const dirs = ['agents', 'rules', 'guards', 'workflows', 'skills'];
|
|
391
|
+
for (const d of dirs)
|
|
392
|
+
mkdirSync(join(agentDir, d), { recursive: true });
|
|
393
|
+
// Core files
|
|
394
|
+
const coreFiles = {
|
|
395
|
+
'INDEX.md': this.genIndex(),
|
|
396
|
+
'AGENT-CARD-SCHEMA.md': this.genSchema(),
|
|
397
|
+
'agents/AGENT-ORCHESTRATOR.md': this.genOrchestrator(),
|
|
398
|
+
'agents/SECURITY-AUDITOR.md': this.genSecurityAgent(),
|
|
399
|
+
'agents/QA-TEST-ENGINEER.md': this.genQAAgent(),
|
|
400
|
+
'agents/TECH-DEBT-CONTROLLER.md': this.genTechDebtAgent(),
|
|
401
|
+
'rules/00-general.md': this.genGeneralRules(),
|
|
402
|
+
'rules/01-architecture.md': this.genArchitectureRules(),
|
|
403
|
+
'rules/02-security.md': this.genSecurityRules(),
|
|
404
|
+
'guards/PREFLIGHT.md': this.genPreflight(),
|
|
405
|
+
'guards/QUALITY-GATES.md': this.genQualityGates(),
|
|
406
|
+
'guards/CODE-REVIEW-CHECKLIST.md': this.genCodeReview(),
|
|
407
|
+
'workflows/develop.md': this.genDevelopWorkflow(),
|
|
408
|
+
'workflows/fix-bug.md': this.genFixBugWorkflow(),
|
|
409
|
+
'workflows/review.md': this.genReviewWorkflow(),
|
|
410
|
+
};
|
|
411
|
+
// Stack-specific agents
|
|
412
|
+
if (this.stack.hasBackend) {
|
|
413
|
+
coreFiles[`agents/${this.stack.primary.toUpperCase()}-BACKEND-DEVELOPER.md`] =
|
|
414
|
+
this.genBackendAgent();
|
|
415
|
+
coreFiles[`rules/03-${this.stack.primary.toLowerCase()}.md`] =
|
|
416
|
+
this.genStackRules();
|
|
417
|
+
}
|
|
418
|
+
if (this.stack.hasFrontend) {
|
|
419
|
+
const fwName = this.stack.frameworks.find(f => ['Angular', 'Vue', 'Next.js', 'React'].includes(f)) || 'Frontend';
|
|
420
|
+
coreFiles[`agents/${fwName.toUpperCase().replace('.', '')}-FRONTEND-DEVELOPER.md`] =
|
|
421
|
+
this.genFrontendAgent();
|
|
422
|
+
}
|
|
423
|
+
if (this.stack.hasMobile) {
|
|
424
|
+
coreFiles['agents/FLUTTER-UI-DEVELOPER.md'] = this.genMobileAgent();
|
|
425
|
+
}
|
|
426
|
+
if (this.stack.hasDatabase) {
|
|
427
|
+
coreFiles['agents/DATABASE-ENGINEER.md'] = this.genDatabaseAgent();
|
|
428
|
+
}
|
|
429
|
+
for (const [path, content] of Object.entries(coreFiles)) {
|
|
430
|
+
writeFileSync(join(agentDir, path), content);
|
|
431
|
+
generated.push(path);
|
|
432
|
+
}
|
|
433
|
+
return generated;
|
|
434
|
+
}
|
|
435
|
+
getTemplateFor(category, file) {
|
|
436
|
+
if (file.includes('ORCHESTRATOR'))
|
|
437
|
+
return this.genOrchestrator();
|
|
438
|
+
if (file.includes('SECURITY'))
|
|
439
|
+
return this.genSecurityAgent();
|
|
440
|
+
if (file.includes('QA'))
|
|
441
|
+
return this.genQAAgent();
|
|
442
|
+
if (file.includes('TECH-DEBT'))
|
|
443
|
+
return this.genTechDebtAgent();
|
|
444
|
+
if (file.includes('BACKEND'))
|
|
445
|
+
return this.genBackendAgent();
|
|
446
|
+
if (file.includes('FRONTEND'))
|
|
447
|
+
return this.genFrontendAgent();
|
|
448
|
+
if (file.includes('INDEX'))
|
|
449
|
+
return this.genIndex();
|
|
450
|
+
if (file.includes('00-general'))
|
|
451
|
+
return this.genGeneralRules();
|
|
452
|
+
if (file.includes('PREFLIGHT'))
|
|
453
|
+
return this.genPreflight();
|
|
454
|
+
if (file.includes('develop'))
|
|
455
|
+
return this.genDevelopWorkflow();
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
// ── Template Generators ──
|
|
459
|
+
get projectName() {
|
|
460
|
+
return this.report.projectInfo.name || 'Project';
|
|
461
|
+
}
|
|
462
|
+
get stackLabel() {
|
|
463
|
+
return [
|
|
464
|
+
...this.stack.languages,
|
|
465
|
+
...this.stack.frameworks,
|
|
466
|
+
].join(' + ');
|
|
467
|
+
}
|
|
468
|
+
genIndex() {
|
|
469
|
+
const agents = [
|
|
470
|
+
'AGENT-ORCHESTRATOR',
|
|
471
|
+
...(this.stack.hasBackend ? [`${this.stack.primary.toUpperCase()}-BACKEND-DEVELOPER`] : []),
|
|
472
|
+
...(this.stack.hasFrontend ? ['FRONTEND-DEVELOPER'] : []),
|
|
473
|
+
...(this.stack.hasMobile ? ['FLUTTER-UI-DEVELOPER'] : []),
|
|
474
|
+
...(this.stack.hasDatabase ? ['DATABASE-ENGINEER'] : []),
|
|
475
|
+
'SECURITY-AUDITOR',
|
|
476
|
+
'QA-TEST-ENGINEER',
|
|
477
|
+
'TECH-DEBT-CONTROLLER',
|
|
478
|
+
];
|
|
479
|
+
return `# ${this.projectName} — Agent Framework
|
|
480
|
+
|
|
481
|
+
> **Auto-generated by [Architect v2.1](https://github.com/camilooscargbaptista/architect)**
|
|
482
|
+
> Stack: **${this.stackLabel}** | Score: **${this.report.score.overall}/100**
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 🔴 Leitura Obrigatória
|
|
487
|
+
|
|
488
|
+
| # | Arquivo | Propósito |
|
|
489
|
+
|---|---------|-----------|
|
|
490
|
+
| 1 | [00-general.md](./rules/00-general.md) | Regras gerais do projeto |
|
|
491
|
+
| 2 | [PREFLIGHT.md](./guards/PREFLIGHT.md) | Checklist pré-ação |
|
|
492
|
+
| 3 | [QUALITY-GATES.md](./guards/QUALITY-GATES.md) | Critérios mínimos |
|
|
493
|
+
|
|
494
|
+
## 🤖 Agentes Disponíveis
|
|
495
|
+
|
|
496
|
+
| Agente | Arquivo | Role |
|
|
497
|
+
|--------|---------|------|
|
|
498
|
+
${agents.map(a => `| ${a} | [${a}.md](./agents/${a}.md) | ${a.includes('ORCHESTRATOR') ? 'coordination' : a.includes('SECURITY') || a.includes('QA') ? 'quality' : 'development'} |`).join('\n')}
|
|
499
|
+
|
|
500
|
+
## 📁 Estrutura
|
|
501
|
+
|
|
502
|
+
\`\`\`
|
|
503
|
+
.agent/
|
|
504
|
+
├── agents/ → Agentes especializados
|
|
505
|
+
├── rules/ → Regras de codificação
|
|
506
|
+
├── guards/ → Checklists e quality gates
|
|
507
|
+
├── workflows/ → Fluxos de trabalho
|
|
508
|
+
└── skills/ → Padrões e referências
|
|
509
|
+
\`\`\`
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
**⚠️ REGRA DE OURO: Na dúvida, PARA e PERGUNTA.**
|
|
514
|
+
`;
|
|
515
|
+
}
|
|
516
|
+
genSchema() {
|
|
517
|
+
return `---
|
|
518
|
+
description: 'Schema de referência para Agent Cards — padrão A2A-inspired'
|
|
519
|
+
version: 1.0.0
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
# Agent Card Schema
|
|
523
|
+
|
|
524
|
+
> Cada agente DEVE ter um bloco \`agent_card\` no frontmatter YAML.
|
|
525
|
+
|
|
526
|
+
## Schema
|
|
527
|
+
|
|
528
|
+
\`\`\`yaml
|
|
529
|
+
agent_card:
|
|
530
|
+
id: "string" # kebab-case unique ID
|
|
531
|
+
name: "string" # Human readable name
|
|
532
|
+
role: "enum" # coordination | development | quality | protection | governance
|
|
533
|
+
capabilities: [] # List of skills
|
|
534
|
+
inputs: [] # What the agent needs
|
|
535
|
+
outputs: [] # What the agent produces
|
|
536
|
+
depends_on: [] # Agents that must run before
|
|
537
|
+
\`\`\`
|
|
538
|
+
|
|
539
|
+
## Roles
|
|
540
|
+
|
|
541
|
+
| Role | Description |
|
|
542
|
+
|------|-------------|
|
|
543
|
+
| coordination | Orchestrates other agents |
|
|
544
|
+
| development | Writes production code |
|
|
545
|
+
| quality | Testing and QA |
|
|
546
|
+
| protection | Security and compliance |
|
|
547
|
+
| governance | Standards and tech debt |
|
|
548
|
+
`;
|
|
549
|
+
}
|
|
550
|
+
genOrchestrator() {
|
|
551
|
+
const layers = this.report.layers.map(l => l.name).join(', ');
|
|
552
|
+
const antiPatterns = this.report.antiPatterns.map(a => a.name).join(', ') || 'None detected';
|
|
553
|
+
return `---
|
|
554
|
+
antigravity:
|
|
555
|
+
trigger: 'always_on'
|
|
556
|
+
globs: ['**/*']
|
|
557
|
+
description: 'META-AGENT ORQUESTRADOR — Coordena todos os agentes para ${this.projectName}'
|
|
558
|
+
priority: CRITICAL
|
|
559
|
+
agent_card:
|
|
560
|
+
id: 'orchestrator'
|
|
561
|
+
name: 'Agent Orchestrator'
|
|
562
|
+
role: 'coordination'
|
|
563
|
+
capabilities: [request-decomposition, agent-dispatch, plan-consolidation, quality-verification]
|
|
564
|
+
inputs: [user-story, feature-request, bug-report, refactoring-request]
|
|
565
|
+
outputs: [consolidated-plan, implementation-blocks, effort-estimate]
|
|
566
|
+
depends_on: []
|
|
567
|
+
version: 1.0.0
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
# 🎭 AGENT-ORCHESTRATOR: ${this.projectName}
|
|
571
|
+
|
|
572
|
+
> **Centro de comando.** Toda requisição passa por aqui.
|
|
573
|
+
|
|
574
|
+
## Contexto do Projeto
|
|
575
|
+
|
|
576
|
+
- **Projeto:** ${this.projectName}
|
|
577
|
+
- **Stack:** ${this.stackLabel}
|
|
578
|
+
- **Score Atual:** ${this.report.score.overall}/100
|
|
579
|
+
- **Camadas:** ${layers}
|
|
580
|
+
- **Anti-Patterns:** ${antiPatterns}
|
|
581
|
+
- **Arquivos:** ${this.report.projectInfo.totalFiles} files, ${this.report.projectInfo.totalLines} lines
|
|
582
|
+
|
|
583
|
+
## Missão
|
|
584
|
+
|
|
585
|
+
\`\`\`
|
|
586
|
+
RECEBER REQUISIÇÃO
|
|
587
|
+
↓
|
|
588
|
+
ENTENDER CONTEXTO
|
|
589
|
+
↓
|
|
590
|
+
DISPARAR AGENTES (paralelo)
|
|
591
|
+
↓
|
|
592
|
+
CONSOLIDAR ANÁLISES
|
|
593
|
+
↓
|
|
594
|
+
APRESENTAR PLANO
|
|
595
|
+
↓
|
|
596
|
+
AGUARDAR APROVAÇÃO
|
|
597
|
+
↓
|
|
598
|
+
DELEGAR IMPLEMENTAÇÃO
|
|
599
|
+
↓
|
|
600
|
+
VERIFICAR QUALIDADE
|
|
601
|
+
\`\`\`
|
|
602
|
+
|
|
603
|
+
## Protocolo de Recepção
|
|
604
|
+
|
|
605
|
+
### FASE 0: Parsing da Requisição
|
|
606
|
+
|
|
607
|
+
\`\`\`
|
|
608
|
+
✓ Nome da feature/fix: _______________
|
|
609
|
+
✓ Tipo: [ ] Feature [ ] Bug Fix [ ] Refactoring [ ] Documentation
|
|
610
|
+
✓ Camadas tocadas: ${layers}
|
|
611
|
+
✓ Complexidade: [ ] XS [ ] S [ ] M [ ] L [ ] XL
|
|
612
|
+
✓ Assunções (listar): _______________
|
|
613
|
+
\`\`\`
|
|
614
|
+
|
|
615
|
+
### FASE 1: Disparo de Agentes
|
|
616
|
+
|
|
617
|
+
\`\`\`
|
|
618
|
+
ORQUESTRADOR analisa requisição
|
|
619
|
+
│
|
|
620
|
+
${this.stack.hasBackend ? ` ├──→ [${this.stack.primary.toUpperCase()}-BACKEND]\n │ • Arquitetura de serviços\n │ • API contracts\n │ • Lógica de negócio\n │\n` : ''}${this.stack.hasFrontend ? ` ├──→ [FRONTEND-DEVELOPER]\n │ • Componentes e páginas\n │ • State management\n │ • UX/UI\n │\n` : ''}${this.stack.hasMobile ? ` ├──→ [FLUTTER-UI-DEVELOPER]\n │ • Screens mobile\n │ • Navigation\n │ • Widgets\n │\n` : ''}${this.stack.hasDatabase ? ` ├──→ [DATABASE-ENGINEER]\n │ • Schema design\n │ • Migrations\n │ • Performance\n │\n` : ''} ├──→ [SECURITY-AUDITOR]
|
|
621
|
+
│ • Análise de ameaças
|
|
622
|
+
│ • Compliance check
|
|
623
|
+
│
|
|
624
|
+
├──→ [QA-TEST-ENGINEER]
|
|
625
|
+
│ • Test plan
|
|
626
|
+
│ • Coverage targets
|
|
627
|
+
│
|
|
628
|
+
└──→ [TECH-DEBT-CONTROLLER]
|
|
629
|
+
• Débito técnico existente
|
|
630
|
+
• Refatorações pré-requisito
|
|
631
|
+
\`\`\`
|
|
632
|
+
|
|
633
|
+
### FASE 2: Consolidação
|
|
634
|
+
|
|
635
|
+
O orquestrador consolida em um plano com:
|
|
636
|
+
- Diagrama de arquitetura
|
|
637
|
+
- Cenários BDD
|
|
638
|
+
- Plano de testes
|
|
639
|
+
- Estimativa de esforço
|
|
640
|
+
- Riscos e mitigações
|
|
641
|
+
|
|
642
|
+
### FASE 3: Implementação
|
|
643
|
+
|
|
644
|
+
Após \`/approved\`, delegar em blocos ordenados por dependência.
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
## Quality Gates
|
|
649
|
+
|
|
650
|
+
\`\`\`
|
|
651
|
+
□ Testes passando
|
|
652
|
+
□ Build compilando
|
|
653
|
+
□ Score >= ${Math.max(this.report.score.overall, 70)}/100
|
|
654
|
+
□ Sem regressão de score
|
|
655
|
+
□ Code review aprovado
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
**Gerado por Architect v2.1 · Score: ${this.report.score.overall}/100**
|
|
661
|
+
`;
|
|
662
|
+
}
|
|
663
|
+
genBackendAgent() {
|
|
664
|
+
const lang = this.stack.primary;
|
|
665
|
+
const fw = this.stack.frameworks.filter(f => ['Django', 'Flask', 'FastAPI', 'NestJS', 'Spring', 'Express'].includes(f)).join(', ') || lang;
|
|
666
|
+
return `---
|
|
667
|
+
antigravity:
|
|
668
|
+
trigger: 'on_demand'
|
|
669
|
+
globs: ['**/*.${lang === 'Python' ? 'py' : 'ts'}']
|
|
670
|
+
description: '${lang} Backend Developer — Arquitetura, APIs, serviços'
|
|
671
|
+
agent_card:
|
|
672
|
+
id: '${lang.toLowerCase()}-backend'
|
|
673
|
+
name: '${lang} Backend Developer'
|
|
674
|
+
role: 'development'
|
|
675
|
+
capabilities: [api-design, service-architecture, business-logic, data-modeling]
|
|
676
|
+
inputs: [user-story, api-contracts, business-rules]
|
|
677
|
+
outputs: [controllers, services, entities, migrations, tests]
|
|
678
|
+
depends_on: [${this.stack.hasDatabase ? 'database-engineer' : ''}]
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
# 🔧 ${lang.toUpperCase()} BACKEND DEVELOPER
|
|
682
|
+
|
|
683
|
+
> Especialista em backend ${fw} para ${this.projectName}
|
|
684
|
+
|
|
685
|
+
## Stack
|
|
686
|
+
|
|
687
|
+
- **Linguagem:** ${lang}
|
|
688
|
+
- **Framework:** ${fw}
|
|
689
|
+
- **Teste:** ${this.stack.testFramework}
|
|
690
|
+
- **Package Manager:** ${this.stack.packageManager}
|
|
691
|
+
|
|
692
|
+
## Princípios
|
|
693
|
+
|
|
694
|
+
1. **SOLID** — Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion
|
|
695
|
+
2. **Clean Architecture** — Separação de camadas
|
|
696
|
+
3. **DRY** — Don't Repeat Yourself
|
|
697
|
+
4. **KISS** — Keep It Simple
|
|
698
|
+
5. **Fail Fast** — Validação na entrada
|
|
699
|
+
|
|
700
|
+
## Padrões de Código
|
|
701
|
+
|
|
702
|
+
### Estrutura de Módulo
|
|
703
|
+
|
|
704
|
+
\`\`\`
|
|
705
|
+
src/modules/[nome]/
|
|
706
|
+
├── [nome].module.${lang === 'Python' ? 'py' : 'ts'}
|
|
707
|
+
├── [nome].controller.${lang === 'Python' ? 'py' : 'ts'}
|
|
708
|
+
├── [nome].service.${lang === 'Python' ? 'py' : 'ts'}
|
|
709
|
+
├── dto/
|
|
710
|
+
├── entities/
|
|
711
|
+
└── __tests__/
|
|
712
|
+
\`\`\`
|
|
713
|
+
|
|
714
|
+
### Convenções
|
|
715
|
+
|
|
716
|
+
| Item | Padrão | Exemplo |
|
|
717
|
+
|------|--------|---------|
|
|
718
|
+
| Classes | PascalCase | \`UserService\` |
|
|
719
|
+
| Funções | camelCase / snake_case | \`get_user\` / \`getUser\` |
|
|
720
|
+
| Constantes | UPPER_SNAKE | \`MAX_RETRIES\` |
|
|
721
|
+
| Arquivos | kebab-case | \`user-service.${lang === 'Python' ? 'py' : 'ts'}\` |
|
|
722
|
+
|
|
723
|
+
## Checklist por Entrega
|
|
724
|
+
|
|
725
|
+
\`\`\`
|
|
726
|
+
□ Tipos/interfaces definidos
|
|
727
|
+
□ Validação de entrada implementada
|
|
728
|
+
□ Erros tratados com mensagens claras
|
|
729
|
+
□ Testes unitários (mínimo 60%)
|
|
730
|
+
□ Sem secrets hardcoded
|
|
731
|
+
□ Logging adequado
|
|
732
|
+
□ Documentação de API
|
|
733
|
+
\`\`\`
|
|
734
|
+
|
|
735
|
+
---
|
|
736
|
+
|
|
737
|
+
**Gerado por Architect v2.1 · Score: ${this.report.score.overall}/100**
|
|
738
|
+
`;
|
|
739
|
+
}
|
|
740
|
+
genFrontendAgent() {
|
|
741
|
+
const fw = this.stack.frameworks.find(f => ['Angular', 'Vue', 'Next.js', 'React'].includes(f)) || 'Frontend';
|
|
742
|
+
return `---
|
|
743
|
+
antigravity:
|
|
744
|
+
trigger: 'on_demand'
|
|
745
|
+
globs: ['src/**/*.{ts,tsx,vue,html,css}']
|
|
746
|
+
description: '${fw} Frontend Developer — Componentes, páginas, UX'
|
|
747
|
+
agent_card:
|
|
748
|
+
id: 'frontend-developer'
|
|
749
|
+
name: '${fw} Frontend Developer'
|
|
750
|
+
role: 'development'
|
|
751
|
+
capabilities: [component-design, state-management, responsive-ui, accessibility]
|
|
752
|
+
inputs: [mockups, api-contracts, user-stories]
|
|
753
|
+
outputs: [components, pages, services, styles, tests]
|
|
754
|
+
depends_on: ['${this.stack.primary.toLowerCase()}-backend']
|
|
755
|
+
---
|
|
756
|
+
|
|
757
|
+
# 🎨 ${fw.toUpperCase()} FRONTEND DEVELOPER
|
|
758
|
+
|
|
759
|
+
> Especialista em frontend ${fw} para ${this.projectName}
|
|
760
|
+
|
|
761
|
+
## Princípios
|
|
762
|
+
|
|
763
|
+
1. **Component-Driven** — Componentes reutilizáveis
|
|
764
|
+
2. **Responsive First** — Mobile-first design
|
|
765
|
+
3. **Accessibility** — WCAG 2.1 AA compliance
|
|
766
|
+
4. **Performance** — Lazy loading, tree shaking
|
|
767
|
+
|
|
768
|
+
## Checklist
|
|
769
|
+
|
|
770
|
+
\`\`\`
|
|
771
|
+
□ Mockup HTML aprovado ANTES de codar
|
|
772
|
+
□ Componentes reutilizáveis
|
|
773
|
+
□ Estado gerenciado corretamente
|
|
774
|
+
□ Responsivo testado (mobile/tablet/desktop)
|
|
775
|
+
□ Loading states implementados
|
|
776
|
+
□ Error states implementados
|
|
777
|
+
□ Acessibilidade verificada
|
|
778
|
+
□ Performance otimizada
|
|
779
|
+
\`\`\`
|
|
780
|
+
|
|
781
|
+
---
|
|
782
|
+
|
|
783
|
+
**Gerado por Architect v2.1**
|
|
784
|
+
`;
|
|
785
|
+
}
|
|
786
|
+
genMobileAgent() {
|
|
787
|
+
return `---
|
|
788
|
+
antigravity:
|
|
789
|
+
trigger: 'on_demand'
|
|
790
|
+
globs: ['lib/**/*.dart']
|
|
791
|
+
description: 'Flutter UI Developer — Screens, widgets, navigation'
|
|
792
|
+
agent_card:
|
|
793
|
+
id: 'flutter-ui'
|
|
794
|
+
name: 'Flutter UI Developer'
|
|
795
|
+
role: 'development'
|
|
796
|
+
capabilities: [screen-design, widget-composition, navigation, state-management]
|
|
797
|
+
inputs: [mockups, api-contracts]
|
|
798
|
+
outputs: [screens, widgets, blocs, tests]
|
|
799
|
+
depends_on: ['${this.stack.primary.toLowerCase()}-backend']
|
|
800
|
+
---
|
|
801
|
+
|
|
802
|
+
# 📱 FLUTTER UI DEVELOPER
|
|
803
|
+
|
|
804
|
+
> Especialista em mobile Flutter para ${this.projectName}
|
|
805
|
+
|
|
806
|
+
## Padrões
|
|
807
|
+
|
|
808
|
+
- **State:** BLoC / Provider
|
|
809
|
+
- **Navigation:** GoRouter / Navigator 2.0
|
|
810
|
+
- **Architecture:** Clean Architecture
|
|
811
|
+
- **Tests:** flutter_test + integration_test
|
|
812
|
+
|
|
813
|
+
---
|
|
814
|
+
|
|
815
|
+
**Gerado por Architect v2.1**
|
|
816
|
+
`;
|
|
817
|
+
}
|
|
818
|
+
genDatabaseAgent() {
|
|
819
|
+
return `---
|
|
820
|
+
antigravity:
|
|
821
|
+
trigger: 'on_demand'
|
|
822
|
+
globs: ['**/migrations/**', '**/entities/**', '**/models/**']
|
|
823
|
+
description: 'Database Engineer — Schema, migrations, performance'
|
|
824
|
+
agent_card:
|
|
825
|
+
id: 'database-engineer'
|
|
826
|
+
name: 'Database Engineer'
|
|
827
|
+
role: 'development'
|
|
828
|
+
capabilities: [schema-design, migrations, indexing, query-optimization]
|
|
829
|
+
inputs: [business-rules, data-requirements]
|
|
830
|
+
outputs: [migrations, entities, indexes, constraints]
|
|
831
|
+
depends_on: []
|
|
832
|
+
---
|
|
833
|
+
|
|
834
|
+
# 🗄️ DATABASE ENGINEER
|
|
835
|
+
|
|
836
|
+
> Especialista em banco de dados para ${this.projectName}
|
|
837
|
+
|
|
838
|
+
## Regras
|
|
839
|
+
|
|
840
|
+
1. **NUNCA** usar DELETE físico — sempre soft delete
|
|
841
|
+
2. **SEMPRE** criar migration SQL (não ORM auto-generate)
|
|
842
|
+
3. **SEMPRE** adicionar indexes para FKs e campos de busca
|
|
843
|
+
4. **SEMPRE** validar constraints antes de deploy
|
|
844
|
+
|
|
845
|
+
---
|
|
846
|
+
|
|
847
|
+
**Gerado por Architect v2.1**
|
|
848
|
+
`;
|
|
849
|
+
}
|
|
850
|
+
genSecurityAgent() {
|
|
851
|
+
return `---
|
|
852
|
+
antigravity:
|
|
853
|
+
trigger: 'on_demand'
|
|
854
|
+
globs: ['**/*']
|
|
855
|
+
description: 'Security Auditor — Análise de vulnerabilidades e compliance'
|
|
856
|
+
agent_card:
|
|
857
|
+
id: 'security-auditor'
|
|
858
|
+
name: 'Security Auditor'
|
|
859
|
+
role: 'protection'
|
|
860
|
+
capabilities: [threat-modeling, vulnerability-scan, compliance-check, auth-review]
|
|
861
|
+
inputs: [source-code, api-contracts, deployment-config]
|
|
862
|
+
outputs: [security-reports, threat-models, compliance-checklists]
|
|
863
|
+
depends_on: []
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
# 🛡️ SECURITY AUDITOR
|
|
867
|
+
|
|
868
|
+
> Proteção contra ameaças para ${this.projectName}
|
|
869
|
+
|
|
870
|
+
## Checklist de Segurança
|
|
871
|
+
|
|
872
|
+
\`\`\`
|
|
873
|
+
□ Sem secrets/credentials hardcoded
|
|
874
|
+
□ Sem logging de dados sensíveis (passwords, tokens, PII)
|
|
875
|
+
□ Inputs sanitizados
|
|
876
|
+
□ Queries parametrizadas (anti SQL injection)
|
|
877
|
+
□ Autenticação validada em todas as rotas
|
|
878
|
+
□ Autorização (RBAC) verificada
|
|
879
|
+
□ Rate limiting configurado
|
|
880
|
+
□ CORS configurado corretamente
|
|
881
|
+
□ Headers de segurança (HSTS, CSP, X-Frame)
|
|
882
|
+
□ Dependências sem vulnerabilidades conhecidas
|
|
883
|
+
\`\`\`
|
|
884
|
+
|
|
885
|
+
## STRIDE Threat Model
|
|
886
|
+
|
|
887
|
+
| Ameaça | Descrição | Mitigação |
|
|
888
|
+
|--------|-----------|-----------|
|
|
889
|
+
| **S**poofing | Falsificação de identidade | JWT + MFA |
|
|
890
|
+
| **T**ampering | Alteração de dados | Validação + Checksums |
|
|
891
|
+
| **R**epudiation | Negação de ações | Audit logs |
|
|
892
|
+
| **I**nformation Disclosure | Vazamento de dados | Encryption + RBAC |
|
|
893
|
+
| **D**enial of Service | Indisponibilidade | Rate limiting + WAF |
|
|
894
|
+
| **E**levation of Privilege | Escalação de permissões | RBAC + Least privilege |
|
|
895
|
+
|
|
896
|
+
---
|
|
897
|
+
|
|
898
|
+
**Gerado por Architect v2.1 · Score: ${this.report.score.overall}/100**
|
|
899
|
+
`;
|
|
900
|
+
}
|
|
901
|
+
genQAAgent() {
|
|
902
|
+
return `---
|
|
903
|
+
antigravity:
|
|
904
|
+
trigger: 'on_demand'
|
|
905
|
+
globs: ['**/*.{test,spec}.*', '**/__tests__/**']
|
|
906
|
+
description: 'QA Test Engineer — Testes, cobertura, qualidade'
|
|
907
|
+
agent_card:
|
|
908
|
+
id: 'qa-test-engineer'
|
|
909
|
+
name: 'QA Test Engineer'
|
|
910
|
+
role: 'quality'
|
|
911
|
+
capabilities: [bdd-specs, unit-tests, integration-tests, e2e-tests, coverage-analysis]
|
|
912
|
+
inputs: [user-stories, api-contracts, business-rules]
|
|
913
|
+
outputs: [test-suites, bdd-scenarios, coverage-reports]
|
|
914
|
+
depends_on: []
|
|
915
|
+
---
|
|
916
|
+
|
|
917
|
+
# 🧪 QA TEST ENGINEER
|
|
918
|
+
|
|
919
|
+
> Qualidade e testes para ${this.projectName}
|
|
920
|
+
|
|
921
|
+
## Stack de Testes
|
|
922
|
+
|
|
923
|
+
- **Framework:** ${this.stack.testFramework}
|
|
924
|
+
- **Cobertura mínima:** 60%
|
|
925
|
+
- **Padrão:** TDD (Red → Green → Refactor)
|
|
926
|
+
|
|
927
|
+
## Fluxo TDD
|
|
928
|
+
|
|
929
|
+
\`\`\`
|
|
930
|
+
1. RED → Escrever teste que FALHA
|
|
931
|
+
2. GREEN → Código MÍNIMO para passar
|
|
932
|
+
3. REFACTOR → Limpar sem quebrar
|
|
933
|
+
\`\`\`
|
|
934
|
+
|
|
935
|
+
## Cenários Obrigatórios
|
|
936
|
+
|
|
937
|
+
\`\`\`
|
|
938
|
+
□ Happy path (fluxo principal)
|
|
939
|
+
□ Validação de entrada (dados inválidos)
|
|
940
|
+
□ Edge cases (limites, null, empty)
|
|
941
|
+
□ Erro handling (exceptions, timeouts)
|
|
942
|
+
□ Permissões (autorizado vs não autorizado)
|
|
943
|
+
□ Fluxos existentes NÃO quebrados
|
|
944
|
+
\`\`\`
|
|
945
|
+
|
|
946
|
+
## Padrão BDD
|
|
947
|
+
|
|
948
|
+
\`\`\`gherkin
|
|
949
|
+
Feature: [Nome]
|
|
950
|
+
Scenario: [Happy Path]
|
|
951
|
+
Given [contexto]
|
|
952
|
+
When [ação]
|
|
953
|
+
Then [resultado esperado]
|
|
954
|
+
|
|
955
|
+
Scenario: [Erro]
|
|
956
|
+
Given [contexto]
|
|
957
|
+
When [ação inválida]
|
|
958
|
+
Then [erro esperado]
|
|
959
|
+
\`\`\`
|
|
960
|
+
|
|
961
|
+
---
|
|
962
|
+
|
|
963
|
+
**Gerado por Architect v2.1**
|
|
964
|
+
`;
|
|
965
|
+
}
|
|
966
|
+
genTechDebtAgent() {
|
|
967
|
+
const steps = this.plan.steps.map(s => `| ${s.priority} | ${s.title} | ${s.operations.length} ops |`).join('\n');
|
|
968
|
+
return `---
|
|
969
|
+
antigravity:
|
|
970
|
+
trigger: 'on_demand'
|
|
971
|
+
globs: ['**/*']
|
|
972
|
+
description: 'Tech Debt Controller — Identifica e prioriza débito técnico'
|
|
973
|
+
agent_card:
|
|
974
|
+
id: 'tech-debt-controller'
|
|
975
|
+
name: 'Tech Debt Controller'
|
|
976
|
+
role: 'governance'
|
|
977
|
+
capabilities: [debt-identification, refactoring-planning, pattern-enforcement]
|
|
978
|
+
inputs: [architecture-report, anti-patterns, code-metrics]
|
|
979
|
+
outputs: [debt-backlog, refactoring-plans, improvement-metrics]
|
|
980
|
+
depends_on: []
|
|
981
|
+
---
|
|
982
|
+
|
|
983
|
+
# 📊 TECH DEBT CONTROLLER
|
|
984
|
+
|
|
985
|
+
> Governança de débito técnico para ${this.projectName}
|
|
986
|
+
|
|
987
|
+
## Estado Atual
|
|
988
|
+
|
|
989
|
+
- **Score:** ${this.report.score.overall}/100
|
|
990
|
+
- **Anti-patterns:** ${this.report.antiPatterns.length}
|
|
991
|
+
- **Refactoring steps:** ${this.plan.steps.length}
|
|
992
|
+
|
|
993
|
+
## Backlog de Refactoring
|
|
994
|
+
|
|
995
|
+
| Prioridade | Item | Operações |
|
|
996
|
+
|------------|------|-----------|
|
|
997
|
+
${steps || '| — | Nenhum item pendente | — |'}
|
|
998
|
+
|
|
999
|
+
## Taxonomia de Dívida
|
|
1000
|
+
|
|
1001
|
+
| Tipo | Descrição | Impacto |
|
|
1002
|
+
|------|-----------|---------|
|
|
1003
|
+
| Architecture | Violações de camadas, hubs | Score |
|
|
1004
|
+
| Code Quality | Complexidade, duplicação | Manutenção |
|
|
1005
|
+
| Testing | Cobertura baixa, sem testes | Confiabilidade |
|
|
1006
|
+
| Security | Vulnerabilidades conhecidas | Risco |
|
|
1007
|
+
| Documentation | Docs ausentes ou desatualizados | Onboarding |
|
|
1008
|
+
|
|
1009
|
+
---
|
|
1010
|
+
|
|
1011
|
+
**Gerado por Architect v2.1 · Score: ${this.report.score.overall}/100**
|
|
1012
|
+
`;
|
|
1013
|
+
}
|
|
1014
|
+
genGeneralRules() {
|
|
1015
|
+
return `---
|
|
1016
|
+
antigravity:
|
|
1017
|
+
trigger: 'always_on'
|
|
1018
|
+
globs: ['**/*']
|
|
1019
|
+
description: 'Regras gerais obrigatórias — ${this.projectName}'
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
# ${this.projectName} — Regras Gerais
|
|
1023
|
+
|
|
1024
|
+
> **LEIA TUDO ANTES DE QUALQUER AÇÃO.**
|
|
1025
|
+
|
|
1026
|
+
## 🥇 REGRAS DE OURO (INVIOLÁVEIS)
|
|
1027
|
+
|
|
1028
|
+
\`\`\`
|
|
1029
|
+
🥇 1. GIT FLOW COMPLETO
|
|
1030
|
+
→ Verificar branch + status ANTES de tudo
|
|
1031
|
+
→ feature/* → develop → staging → main
|
|
1032
|
+
→ NUNCA codificar direto em main/staging/develop
|
|
1033
|
+
|
|
1034
|
+
🥇 2. DIAGNÓSTICO ANTES DE CODAR
|
|
1035
|
+
→ Ler código existente ANTES de implementar
|
|
1036
|
+
→ Verificar se já existe algo similar
|
|
1037
|
+
|
|
1038
|
+
🥇 3. TDD
|
|
1039
|
+
→ Testes ANTES do código
|
|
1040
|
+
→ Red → Green → Refactor
|
|
1041
|
+
|
|
1042
|
+
🥇 4. NÃO DECIDIR SOZINHO
|
|
1043
|
+
→ Dúvida? PARAR E PERGUNTAR
|
|
1044
|
+
|
|
1045
|
+
🥇 5. QUALIDADE > VELOCIDADE
|
|
1046
|
+
→ Nunca atalhos. Fazer certo da primeira vez.
|
|
1047
|
+
\`\`\`
|
|
1048
|
+
|
|
1049
|
+
## Stack
|
|
1050
|
+
|
|
1051
|
+
| Camada | Tecnologia |
|
|
1052
|
+
|--------|------------|
|
|
1053
|
+
${this.stack.languages.map(l => `| ${l} | ${this.stack.frameworks.filter(f => f).join(', ') || l} |`).join('\n')}
|
|
1054
|
+
|
|
1055
|
+
## Convenções de Idioma
|
|
1056
|
+
|
|
1057
|
+
| Contexto | Idioma |
|
|
1058
|
+
|----------|--------|
|
|
1059
|
+
| Código (variáveis, funções) | Inglês |
|
|
1060
|
+
| Comentários | Português (Brasil) |
|
|
1061
|
+
| Git commits | Inglês (Conventional Commits) |
|
|
1062
|
+
| Documentação | Português (Brasil) |
|
|
1063
|
+
|
|
1064
|
+
## Nomenclatura
|
|
1065
|
+
|
|
1066
|
+
| Tipo | Padrão | Exemplo |
|
|
1067
|
+
|------|--------|---------|
|
|
1068
|
+
| Classes | PascalCase | \`UserService\` |
|
|
1069
|
+
| Funções | camelCase | \`getUser\` |
|
|
1070
|
+
| Constantes | UPPER_SNAKE | \`MAX_RETRIES\` |
|
|
1071
|
+
| Arquivos | kebab-case | \`user-service.ts\` |
|
|
1072
|
+
|
|
1073
|
+
## ⛔ O QUE NUNCA FAZER
|
|
1074
|
+
|
|
1075
|
+
\`\`\`
|
|
1076
|
+
❌ Commitar em main/staging/develop
|
|
1077
|
+
❌ Pular Git Flow
|
|
1078
|
+
❌ Assumir — VERIFICAR
|
|
1079
|
+
❌ Dizer "pronto" sem testes
|
|
1080
|
+
❌ Hardcoded secrets
|
|
1081
|
+
\`\`\`
|
|
1082
|
+
|
|
1083
|
+
---
|
|
1084
|
+
|
|
1085
|
+
**Gerado por Architect v2.1 · Score: ${this.report.score.overall}/100**
|
|
1086
|
+
`;
|
|
1087
|
+
}
|
|
1088
|
+
genArchitectureRules() {
|
|
1089
|
+
const layers = this.report.layers.map(l => `| ${l.name} | ${l.files.length} files | ${l.description} |`).join('\n');
|
|
1090
|
+
return `---
|
|
1091
|
+
antigravity:
|
|
1092
|
+
trigger: 'always_on'
|
|
1093
|
+
globs: ['**/*']
|
|
1094
|
+
description: 'Regras de arquitetura — ${this.projectName}'
|
|
1095
|
+
---
|
|
1096
|
+
|
|
1097
|
+
# Regras de Arquitetura
|
|
1098
|
+
|
|
1099
|
+
## Camadas Detectadas
|
|
1100
|
+
|
|
1101
|
+
| Camada | Arquivos | Descrição |
|
|
1102
|
+
|--------|----------|-----------|
|
|
1103
|
+
${layers}
|
|
1104
|
+
|
|
1105
|
+
## Score Atual: ${this.report.score.overall}/100
|
|
1106
|
+
|
|
1107
|
+
| Métrica | Valor |
|
|
1108
|
+
|---------|-------|
|
|
1109
|
+
| Modularity | ${this.report.score.breakdown.modularity} |
|
|
1110
|
+
| Coupling | ${this.report.score.breakdown.coupling} |
|
|
1111
|
+
| Cohesion | ${this.report.score.breakdown.cohesion} |
|
|
1112
|
+
| Layering | ${this.report.score.breakdown.layering} |
|
|
1113
|
+
|
|
1114
|
+
## Regras
|
|
1115
|
+
|
|
1116
|
+
1. **Respeitar camadas** — Nunca importar de camada superior
|
|
1117
|
+
2. **Máximo 5 dependências** — Acima disso, considerar split
|
|
1118
|
+
3. **Sem imports circulares** — Sempre unidirecional
|
|
1119
|
+
4. **Um propósito por arquivo** — Single Responsibility
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1123
|
+
**Gerado por Architect v2.1**
|
|
1124
|
+
`;
|
|
1125
|
+
}
|
|
1126
|
+
genSecurityRules() {
|
|
1127
|
+
return `---
|
|
1128
|
+
antigravity:
|
|
1129
|
+
trigger: 'always_on'
|
|
1130
|
+
globs: ['**/*']
|
|
1131
|
+
description: 'Regras de segurança — ${this.projectName}'
|
|
1132
|
+
---
|
|
1133
|
+
|
|
1134
|
+
# Regras de Segurança
|
|
1135
|
+
|
|
1136
|
+
## NUNCA (Zero Tolerância)
|
|
1137
|
+
|
|
1138
|
+
\`\`\`
|
|
1139
|
+
❌ Hardcoded secrets, API keys, passwords
|
|
1140
|
+
❌ Logging de dados sensíveis (PII, tokens)
|
|
1141
|
+
❌ SQL sem parameterização
|
|
1142
|
+
❌ eval() ou exec() com input do usuário
|
|
1143
|
+
❌ Endpoints sem autenticação
|
|
1144
|
+
❌ CORS com wildcard (*) em produção
|
|
1145
|
+
\`\`\`
|
|
1146
|
+
|
|
1147
|
+
## SEMPRE
|
|
1148
|
+
|
|
1149
|
+
\`\`\`
|
|
1150
|
+
✅ Sanitizar inputs do usuário
|
|
1151
|
+
✅ Usar queries parametrizadas
|
|
1152
|
+
✅ Validar file uploads (tipo, tamanho)
|
|
1153
|
+
✅ Rate limiting em APIs públicas
|
|
1154
|
+
✅ Headers de segurança (HSTS, CSP)
|
|
1155
|
+
✅ Audit logs para ações sensíveis
|
|
1156
|
+
\`\`\`
|
|
1157
|
+
|
|
1158
|
+
---
|
|
1159
|
+
|
|
1160
|
+
**Gerado por Architect v2.1**
|
|
1161
|
+
`;
|
|
1162
|
+
}
|
|
1163
|
+
genStackRules() {
|
|
1164
|
+
const lang = this.stack.primary;
|
|
1165
|
+
return `---
|
|
1166
|
+
antigravity:
|
|
1167
|
+
trigger: 'on_demand'
|
|
1168
|
+
globs: ['**/*.${lang === 'Python' ? 'py' : lang === 'TypeScript' ? 'ts' : lang.toLowerCase()}']
|
|
1169
|
+
description: 'Regras específicas de ${lang} — ${this.projectName}'
|
|
1170
|
+
---
|
|
1171
|
+
|
|
1172
|
+
# Regras ${lang}
|
|
1173
|
+
|
|
1174
|
+
## Boas Práticas
|
|
1175
|
+
|
|
1176
|
+
${lang === 'Python' ? `
|
|
1177
|
+
- Type hints em TODAS as funções
|
|
1178
|
+
- Docstrings em classes e funções públicas
|
|
1179
|
+
- PEP 8 compliance
|
|
1180
|
+
- Use \`pathlib\` ao invés de \`os.path\`
|
|
1181
|
+
- Use \`dataclasses\` ou \`pydantic\` para modelos
|
|
1182
|
+
- Virtual environment obrigatório
|
|
1183
|
+
` : lang === 'TypeScript' ? `
|
|
1184
|
+
- Strict mode ativado
|
|
1185
|
+
- Interfaces para TODOS os contratos
|
|
1186
|
+
- Sem \`any\` (use \`unknown\` se necessário)
|
|
1187
|
+
- Async/await ao invés de callbacks
|
|
1188
|
+
- Enum ao invés de magic strings
|
|
1189
|
+
- JSDoc em funções públicas
|
|
1190
|
+
` : `
|
|
1191
|
+
- Siga as convenções da linguagem
|
|
1192
|
+
- Documentação obrigatória
|
|
1193
|
+
- Testes unitários mínimo 60%
|
|
1194
|
+
`}
|
|
1195
|
+
|
|
1196
|
+
---
|
|
1197
|
+
|
|
1198
|
+
**Gerado por Architect v2.1**
|
|
1199
|
+
`;
|
|
1200
|
+
}
|
|
1201
|
+
genPreflight() {
|
|
1202
|
+
return `# PREFLIGHT Checklist — ${this.projectName}
|
|
1203
|
+
|
|
1204
|
+
> **Execute ANTES de qualquer tarefa. Sem exceções.**
|
|
1205
|
+
|
|
1206
|
+
## 🔴 Fase 0: Preparação
|
|
1207
|
+
|
|
1208
|
+
\`\`\`
|
|
1209
|
+
□ Li e entendi a tarefa completamente?
|
|
1210
|
+
□ Sei qual é o objetivo?
|
|
1211
|
+
□ Identifiquei o tipo: [ ] Backend [ ] Frontend [ ] Database [ ] Bug Fix [ ] Feature
|
|
1212
|
+
\`\`\`
|
|
1213
|
+
|
|
1214
|
+
## 🔴 Fase 1: Ambiente
|
|
1215
|
+
|
|
1216
|
+
\`\`\`
|
|
1217
|
+
□ Qual branch estou? → git branch --show-current
|
|
1218
|
+
□ É main ou develop? → CRIAR BRANCH IMEDIATAMENTE
|
|
1219
|
+
□ Branch atualizada? → git pull origin develop
|
|
1220
|
+
\`\`\`
|
|
1221
|
+
|
|
1222
|
+
## 🔴 Fase 2: Diagnóstico
|
|
1223
|
+
|
|
1224
|
+
\`\`\`
|
|
1225
|
+
□ Verifiquei código existente similar?
|
|
1226
|
+
□ Entendi a arquitetura afetada?
|
|
1227
|
+
□ Li lessons-learned (se existir)?
|
|
1228
|
+
\`\`\`
|
|
1229
|
+
|
|
1230
|
+
## ⚠️ Red Flags - PARE
|
|
1231
|
+
|
|
1232
|
+
| Red Flag | Ação |
|
|
1233
|
+
|----------|------|
|
|
1234
|
+
| Não sei onde fica o código | Pesquisar ANTES |
|
|
1235
|
+
| Vou assumir algo | PERGUNTAR |
|
|
1236
|
+
| Estou em main/develop | CRIAR BRANCH |
|
|
1237
|
+
| "Acho que funciona" | TESTAR |
|
|
1238
|
+
|
|
1239
|
+
---
|
|
1240
|
+
|
|
1241
|
+
**Gerado por Architect v2.1**
|
|
1242
|
+
`;
|
|
1243
|
+
}
|
|
1244
|
+
genQualityGates() {
|
|
1245
|
+
const minScore = Math.max(this.report.score.overall - 5, 60);
|
|
1246
|
+
return `# Quality Gates — ${this.projectName}
|
|
1247
|
+
|
|
1248
|
+
> Score atual: **${this.report.score.overall}/100**
|
|
1249
|
+
|
|
1250
|
+
## Gates Obrigatórios
|
|
1251
|
+
|
|
1252
|
+
| Gate | Critério | Status |
|
|
1253
|
+
|------|----------|--------|
|
|
1254
|
+
| Build | Compila sem erros | ✅ Required |
|
|
1255
|
+
| Lint | Sem erros de lint | ✅ Required |
|
|
1256
|
+
| Tests | Todos passando | ✅ Required |
|
|
1257
|
+
| Coverage | >= 60% | ✅ Required |
|
|
1258
|
+
| Score | >= ${minScore}/100 | ✅ Required |
|
|
1259
|
+
| No Regression | Score não pode cair | ⚠️ Warning |
|
|
1260
|
+
|
|
1261
|
+
## Métricas Atuais
|
|
1262
|
+
|
|
1263
|
+
| Métrica | Valor | Meta |
|
|
1264
|
+
|---------|-------|------|
|
|
1265
|
+
| Modularity | ${this.report.score.breakdown.modularity} | >= 80 |
|
|
1266
|
+
| Coupling | ${this.report.score.breakdown.coupling} | >= 70 |
|
|
1267
|
+
| Cohesion | ${this.report.score.breakdown.cohesion} | >= 80 |
|
|
1268
|
+
| Layering | ${this.report.score.breakdown.layering} | >= 80 |
|
|
1269
|
+
|
|
1270
|
+
---
|
|
1271
|
+
|
|
1272
|
+
**Gerado por Architect v2.1**
|
|
1273
|
+
`;
|
|
1274
|
+
}
|
|
1275
|
+
genCodeReview() {
|
|
1276
|
+
return `# Code Review Checklist — ${this.projectName}
|
|
1277
|
+
|
|
1278
|
+
## Funcionalidade
|
|
1279
|
+
\`\`\`
|
|
1280
|
+
□ Resolve o problema descrito?
|
|
1281
|
+
□ Edge cases tratados?
|
|
1282
|
+
□ Erros tratados com mensagens claras?
|
|
1283
|
+
\`\`\`
|
|
1284
|
+
|
|
1285
|
+
## Qualidade
|
|
1286
|
+
\`\`\`
|
|
1287
|
+
□ Código legível e bem nomeado?
|
|
1288
|
+
□ Sem duplicação desnecessária?
|
|
1289
|
+
□ Princípios SOLID respeitados?
|
|
1290
|
+
□ Complexidade controlada?
|
|
1291
|
+
\`\`\`
|
|
1292
|
+
|
|
1293
|
+
## Segurança
|
|
1294
|
+
\`\`\`
|
|
1295
|
+
□ Sem secrets hardcoded?
|
|
1296
|
+
□ Inputs validados?
|
|
1297
|
+
□ Queries parametrizadas?
|
|
1298
|
+
\`\`\`
|
|
1299
|
+
|
|
1300
|
+
## Testes
|
|
1301
|
+
\`\`\`
|
|
1302
|
+
□ Testes unitários adicionados?
|
|
1303
|
+
□ Cenários de erro testados?
|
|
1304
|
+
□ Cobertura >= 60%?
|
|
1305
|
+
\`\`\`
|
|
1306
|
+
|
|
1307
|
+
---
|
|
1308
|
+
|
|
1309
|
+
**Gerado por Architect v2.1**
|
|
1310
|
+
`;
|
|
1311
|
+
}
|
|
1312
|
+
genDevelopWorkflow() {
|
|
1313
|
+
return `---
|
|
1314
|
+
name: develop
|
|
1315
|
+
description: Fluxo completo de desenvolvimento — ${this.projectName}
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
# Workflow: Desenvolvimento Completo
|
|
1319
|
+
|
|
1320
|
+
## 🎯 FLUXO OBRIGATÓRIO
|
|
1321
|
+
|
|
1322
|
+
\`\`\`
|
|
1323
|
+
0️⃣ GIT FLOW → Criar feature branch
|
|
1324
|
+
1️⃣ ENTENDIMENTO → Perguntas de clarificação
|
|
1325
|
+
2️⃣ DIAGNÓSTICO → Verificar código existente
|
|
1326
|
+
3️⃣ BDD → Cenários Gherkin (APROVAÇÃO)
|
|
1327
|
+
4️⃣ TDD RED → Testes falhando
|
|
1328
|
+
5️⃣ TDD GREEN → Código mínimo
|
|
1329
|
+
6️⃣ REFACTOR → Código limpo
|
|
1330
|
+
7️⃣ GIT COMMIT → Conventional Commits + Push
|
|
1331
|
+
\`\`\`
|
|
1332
|
+
|
|
1333
|
+
## Pontos de Aprovação
|
|
1334
|
+
|
|
1335
|
+
1. Após entendimento
|
|
1336
|
+
2. Após cenários BDD
|
|
1337
|
+
3. Após testes verdes
|
|
1338
|
+
4. Após refatoração
|
|
1339
|
+
5. Após commit e push
|
|
1340
|
+
|
|
1341
|
+
## 🚫 PROIBIDO
|
|
1342
|
+
|
|
1343
|
+
- ❌ Trabalhar direto em develop/main
|
|
1344
|
+
- ❌ Código antes de teste
|
|
1345
|
+
- ❌ Avançar sem aprovação
|
|
1346
|
+
- ❌ Commit sem Conventional Commits
|
|
1347
|
+
|
|
1348
|
+
---
|
|
1349
|
+
|
|
1350
|
+
**Gerado por Architect v2.1**
|
|
1351
|
+
`;
|
|
1352
|
+
}
|
|
1353
|
+
genFixBugWorkflow() {
|
|
1354
|
+
return `---
|
|
1355
|
+
name: fix-bug
|
|
1356
|
+
description: Corrigir bug com diagnóstico completo — ${this.projectName}
|
|
1357
|
+
---
|
|
1358
|
+
|
|
1359
|
+
# Workflow: Fix Bug
|
|
1360
|
+
|
|
1361
|
+
\`\`\`
|
|
1362
|
+
1️⃣ Criar branch fix/nome-do-bug
|
|
1363
|
+
2️⃣ Reproduzir o bug
|
|
1364
|
+
3️⃣ Escrever teste que FALHA reproduzindo o bug
|
|
1365
|
+
4️⃣ Corrigir o código mínimo
|
|
1366
|
+
5️⃣ Teste passa (GREEN)
|
|
1367
|
+
6️⃣ Verificar que não quebrou nada
|
|
1368
|
+
7️⃣ Commit: fix(scope): description
|
|
1369
|
+
\`\`\`
|
|
1370
|
+
|
|
1371
|
+
---
|
|
1372
|
+
|
|
1373
|
+
**Gerado por Architect v2.1**
|
|
1374
|
+
`;
|
|
1375
|
+
}
|
|
1376
|
+
genReviewWorkflow() {
|
|
1377
|
+
return `---
|
|
1378
|
+
name: review
|
|
1379
|
+
description: Code review completo — ${this.projectName}
|
|
1380
|
+
---
|
|
1381
|
+
|
|
1382
|
+
# Workflow: Code Review
|
|
1383
|
+
|
|
1384
|
+
\`\`\`
|
|
1385
|
+
1️⃣ Ler a descrição do PR
|
|
1386
|
+
2️⃣ Verificar diff por arquivo
|
|
1387
|
+
3️⃣ Executar checklist de review
|
|
1388
|
+
4️⃣ Rodar testes localmente
|
|
1389
|
+
5️⃣ Aprovar ou solicitar mudanças
|
|
1390
|
+
\`\`\`
|
|
1391
|
+
|
|
1392
|
+
---
|
|
1393
|
+
|
|
1394
|
+
**Gerado por Architect v2.1**
|
|
1395
|
+
`;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
//# sourceMappingURL=agent-generator.js.map
|