@codexa/cli 9.0.9 → 9.0.11
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/commands/discover.ts +38 -11
- package/commands/patterns.ts +29 -2
- package/commands/sync.ts +12 -1
- package/commands/team.test.ts +253 -0
- package/commands/team.ts +703 -0
- package/db/schema.ts +7 -0
- package/detectors/go.ts +55 -1
- package/detectors/node.ts +39 -1
- package/gates/standards-validator.ts +3 -2
- package/package.json +1 -1
- package/workflow.ts +43 -0
package/commands/team.ts
ADDED
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
import { getDb } from "../db/connection";
|
|
2
|
+
import { initSchema } from "../db/schema";
|
|
3
|
+
import { resolveSpec, resolveSpecOrNull } from "./spec-resolver";
|
|
4
|
+
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────
|
|
6
|
+
// Interfaces
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
export interface TeammateConfig {
|
|
10
|
+
role: string;
|
|
11
|
+
domain: string;
|
|
12
|
+
taskIds: number[];
|
|
13
|
+
spawnPrompt: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TeamSuggestion {
|
|
17
|
+
recommended: boolean;
|
|
18
|
+
mode: "team" | "subagent";
|
|
19
|
+
reason: string;
|
|
20
|
+
envVarSet: boolean;
|
|
21
|
+
teamConfig?: {
|
|
22
|
+
phase: "imp" | "rev" | "architect";
|
|
23
|
+
teammates: TeammateConfig[];
|
|
24
|
+
estimatedParallelism: number;
|
|
25
|
+
leadSpawnInstruction: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────
|
|
30
|
+
// Main Command
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
export function teamSuggest(options: {
|
|
34
|
+
json?: boolean;
|
|
35
|
+
phase?: string;
|
|
36
|
+
spec?: string;
|
|
37
|
+
}): void {
|
|
38
|
+
initSchema();
|
|
39
|
+
const db = getDb();
|
|
40
|
+
|
|
41
|
+
const envVarSet = process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1";
|
|
42
|
+
|
|
43
|
+
// Phase pode ser fornecida ou detectada
|
|
44
|
+
let spec: any = null;
|
|
45
|
+
let phase = options.phase;
|
|
46
|
+
|
|
47
|
+
if (!phase) {
|
|
48
|
+
spec = resolveSpecOrNull(options.spec);
|
|
49
|
+
if (spec) {
|
|
50
|
+
phase = detectPhase(db, spec);
|
|
51
|
+
} else {
|
|
52
|
+
phase = "unknown";
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
spec = resolveSpecOrNull(options.spec);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let result: TeamSuggestion;
|
|
59
|
+
|
|
60
|
+
if (phase === "imp" && spec) {
|
|
61
|
+
result = suggestForImp(db, spec, envVarSet);
|
|
62
|
+
} else if (phase === "rev" && spec) {
|
|
63
|
+
result = suggestForRev(db, spec, envVarSet);
|
|
64
|
+
} else if (phase === "architect") {
|
|
65
|
+
result = suggestForArchitect(db, spec, envVarSet);
|
|
66
|
+
} else {
|
|
67
|
+
result = {
|
|
68
|
+
recommended: false,
|
|
69
|
+
mode: "subagent",
|
|
70
|
+
reason: `Fase atual (${phase}) nao suporta teams.`,
|
|
71
|
+
envVarSet,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (options.json) {
|
|
76
|
+
console.log(JSON.stringify(result, null, 2));
|
|
77
|
+
} else {
|
|
78
|
+
printTeamSuggestion(result);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ─────────────────────────────────────────────────────────────────
|
|
83
|
+
// Phase Detection
|
|
84
|
+
// ─────────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
export function detectPhase(db: any, spec: any): string {
|
|
87
|
+
if (spec.phase === "implementing") return "imp";
|
|
88
|
+
if (spec.phase === "reviewing") return "rev";
|
|
89
|
+
|
|
90
|
+
// Verificar se ha analise arquitetural pendente
|
|
91
|
+
const pendingAnalysis = db
|
|
92
|
+
.query("SELECT id FROM architectural_analyses WHERE status = 'pending' LIMIT 1")
|
|
93
|
+
.get();
|
|
94
|
+
if (pendingAnalysis) return "architect";
|
|
95
|
+
|
|
96
|
+
return spec.phase;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ─────────────────────────────────────────────────────────────────
|
|
100
|
+
// IMP Phase
|
|
101
|
+
// ─────────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
function suggestForImp(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
|
|
104
|
+
// 1. Buscar tasks pending com dependencias satisfeitas
|
|
105
|
+
const allTasks = db
|
|
106
|
+
.query("SELECT * FROM tasks WHERE spec_id = ? AND status = 'pending'")
|
|
107
|
+
.all(spec.id) as any[];
|
|
108
|
+
|
|
109
|
+
const available = allTasks.filter((t: any) => {
|
|
110
|
+
if (!t.depends_on) return true;
|
|
111
|
+
const deps = JSON.parse(t.depends_on) as number[];
|
|
112
|
+
return deps.every((depNum) => {
|
|
113
|
+
const dep = db
|
|
114
|
+
.query("SELECT status FROM tasks WHERE spec_id = ? AND number = ?")
|
|
115
|
+
.get(spec.id, depNum) as any;
|
|
116
|
+
return dep?.status === "done";
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const parallelizable = available.filter((t: any) => t.can_parallel);
|
|
121
|
+
|
|
122
|
+
// 2. Agrupar por dominio (campo agent)
|
|
123
|
+
const byDomain = new Map<string, any[]>();
|
|
124
|
+
for (const task of parallelizable) {
|
|
125
|
+
const domain = task.agent || "general";
|
|
126
|
+
if (!byDomain.has(domain)) byDomain.set(domain, []);
|
|
127
|
+
byDomain.get(domain)!.push(task);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 3. Recomendar se >= 3 tasks em >= 2 dominios
|
|
131
|
+
if (parallelizable.length < 3 || byDomain.size < 2) {
|
|
132
|
+
return {
|
|
133
|
+
recommended: false,
|
|
134
|
+
mode: "subagent",
|
|
135
|
+
reason: `${parallelizable.length} tasks paralelas em ${byDomain.size} dominio(s). Minimo: 3 tasks, 2 dominios.`,
|
|
136
|
+
envVarSet,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!envVarSet) {
|
|
141
|
+
return {
|
|
142
|
+
recommended: true,
|
|
143
|
+
mode: "subagent",
|
|
144
|
+
reason: "Team recomendado mas CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS nao definida. Usando subagent.",
|
|
145
|
+
envVarSet: false,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 4. Gerar teammates
|
|
150
|
+
const teammates: TeammateConfig[] = [];
|
|
151
|
+
for (const [domain, tasks] of byDomain) {
|
|
152
|
+
teammates.push({
|
|
153
|
+
role: `${domain}-implementer`,
|
|
154
|
+
domain,
|
|
155
|
+
taskIds: tasks.map((t: any) => t.id),
|
|
156
|
+
spawnPrompt: buildImpSpawnPrompt(spec, domain, tasks),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
recommended: true,
|
|
162
|
+
mode: "team",
|
|
163
|
+
reason: `${parallelizable.length} tasks paralelas em ${byDomain.size} dominios.`,
|
|
164
|
+
envVarSet: true,
|
|
165
|
+
teamConfig: {
|
|
166
|
+
phase: "imp",
|
|
167
|
+
teammates,
|
|
168
|
+
estimatedParallelism: parallelizable.length,
|
|
169
|
+
leadSpawnInstruction: buildLeadSpawnInstruction(teammates, "imp"),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ─────────────────────────────────────────────────────────────────
|
|
175
|
+
// REV Phase
|
|
176
|
+
// ─────────────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
function suggestForRev(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
|
|
179
|
+
const totalTasks = (db
|
|
180
|
+
.query("SELECT COUNT(*) as count FROM tasks WHERE spec_id = ?")
|
|
181
|
+
.get(spec.id) as any).count;
|
|
182
|
+
|
|
183
|
+
const artifactCount = (db
|
|
184
|
+
.query("SELECT COUNT(*) as count FROM artifacts WHERE spec_id = ?")
|
|
185
|
+
.get(spec.id) as any).count;
|
|
186
|
+
|
|
187
|
+
if (totalTasks < 3 && artifactCount < 5) {
|
|
188
|
+
return {
|
|
189
|
+
recommended: false,
|
|
190
|
+
mode: "subagent",
|
|
191
|
+
reason: `${totalTasks} tasks, ${artifactCount} artefatos. Reviewer unico suficiente.`,
|
|
192
|
+
envVarSet,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!envVarSet) {
|
|
197
|
+
return {
|
|
198
|
+
recommended: true,
|
|
199
|
+
mode: "subagent",
|
|
200
|
+
reason: "Team recomendado mas env var nao definida.",
|
|
201
|
+
envVarSet: false,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const artifactList = (db
|
|
206
|
+
.query("SELECT path FROM artifacts WHERE spec_id = ?")
|
|
207
|
+
.all(spec.id) as any[]).map((a: any) => a.path);
|
|
208
|
+
|
|
209
|
+
const lenses = ["security", "performance", "standards"] as const;
|
|
210
|
+
const teammates: TeammateConfig[] = lenses.map((lens) => ({
|
|
211
|
+
role: `${lens}-reviewer`,
|
|
212
|
+
domain: "review",
|
|
213
|
+
taskIds: [],
|
|
214
|
+
spawnPrompt: buildRevSpawnPrompt(spec, lens, artifactList),
|
|
215
|
+
}));
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
recommended: true,
|
|
219
|
+
mode: "team",
|
|
220
|
+
reason: `${totalTasks} tasks, ${artifactCount} artefatos. 3 reviewers recomendados.`,
|
|
221
|
+
envVarSet: true,
|
|
222
|
+
teamConfig: {
|
|
223
|
+
phase: "rev",
|
|
224
|
+
teammates,
|
|
225
|
+
estimatedParallelism: 3,
|
|
226
|
+
leadSpawnInstruction: buildLeadSpawnInstruction(teammates, "rev"),
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ─────────────────────────────────────────────────────────────────
|
|
232
|
+
// Architect Phase
|
|
233
|
+
// ─────────────────────────────────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
function suggestForArchitect(db: any, spec: any, envVarSet: boolean): TeamSuggestion {
|
|
236
|
+
const analysis = db
|
|
237
|
+
.query("SELECT * FROM architectural_analyses WHERE status = 'pending' ORDER BY id DESC LIMIT 1")
|
|
238
|
+
.get() as any;
|
|
239
|
+
|
|
240
|
+
if (!analysis) {
|
|
241
|
+
return {
|
|
242
|
+
recommended: false,
|
|
243
|
+
mode: "subagent",
|
|
244
|
+
reason: "Nenhuma analise arquitetural pendente.",
|
|
245
|
+
envVarSet,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!envVarSet) {
|
|
250
|
+
return {
|
|
251
|
+
recommended: true,
|
|
252
|
+
mode: "subagent",
|
|
253
|
+
reason: "Team recomendado mas env var nao definida.",
|
|
254
|
+
envVarSet: false,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const project = db.query("SELECT * FROM project LIMIT 1").get() as any;
|
|
259
|
+
const stackSummary = project?.stack ? JSON.parse(project.stack) : {};
|
|
260
|
+
|
|
261
|
+
const teammates: TeammateConfig[] = [
|
|
262
|
+
{
|
|
263
|
+
role: "architect-alpha",
|
|
264
|
+
domain: "architecture",
|
|
265
|
+
taskIds: [],
|
|
266
|
+
spawnPrompt: buildArchitectSpawnPrompt(analysis, stackSummary, "alpha"),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
role: "architect-beta",
|
|
270
|
+
domain: "architecture",
|
|
271
|
+
taskIds: [],
|
|
272
|
+
spawnPrompt: buildArchitectSpawnPrompt(analysis, stackSummary, "beta"),
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
role: "devil-advocate",
|
|
276
|
+
domain: "architecture",
|
|
277
|
+
taskIds: [],
|
|
278
|
+
spawnPrompt: buildDevilAdvocatePrompt(analysis),
|
|
279
|
+
},
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
recommended: true,
|
|
284
|
+
mode: "team",
|
|
285
|
+
reason: `Analise "${analysis.name}" pendente. Hipoteses competidoras recomendadas.`,
|
|
286
|
+
envVarSet: true,
|
|
287
|
+
teamConfig: {
|
|
288
|
+
phase: "architect",
|
|
289
|
+
teammates,
|
|
290
|
+
estimatedParallelism: 3,
|
|
291
|
+
leadSpawnInstruction: buildLeadSpawnInstruction(teammates, "architect"),
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ─────────────────────────────────────────────────────────────────
|
|
297
|
+
// Lead Spawn Instruction (natural language)
|
|
298
|
+
// ─────────────────────────────────────────────────────────────────
|
|
299
|
+
|
|
300
|
+
export function buildLeadSpawnInstruction(teammates: TeammateConfig[], phase: string): string {
|
|
301
|
+
const phaseDescriptions: Record<string, string> = {
|
|
302
|
+
imp: "implement parallel tasks",
|
|
303
|
+
rev: "review artifacts with specialized lenses",
|
|
304
|
+
architect: "propose competing architectural approaches",
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const teammateLines = teammates.map((t) =>
|
|
308
|
+
`- "${t.role}" with the prompt: "${t.spawnPrompt.replace(/"/g, '\\"').substring(0, 200)}..."`
|
|
309
|
+
).join("\n");
|
|
310
|
+
|
|
311
|
+
return `Create an agent team to ${phaseDescriptions[phase] || phase}. Spawn these teammates:
|
|
312
|
+
|
|
313
|
+
${teammateLines}
|
|
314
|
+
|
|
315
|
+
Use delegate mode — do NOT implement anything yourself. Only coordinate, monitor messages, and synthesize results.
|
|
316
|
+
Wait for all teammates to finish before proceeding.`;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ─────────────────────────────────────────────────────────────────
|
|
320
|
+
// Spawn Prompts: IMP
|
|
321
|
+
// ─────────────────────────────────────────────────────────────────
|
|
322
|
+
|
|
323
|
+
export function buildImpSpawnPrompt(spec: any, domain: string, tasks: any[]): string {
|
|
324
|
+
const taskList = tasks.map((t: any) =>
|
|
325
|
+
`- Task #${t.number}: ${t.name} (ID: ${t.id}, arquivos: ${t.files || "a definir"})`
|
|
326
|
+
).join("\n");
|
|
327
|
+
|
|
328
|
+
return `## IDENTIDADE
|
|
329
|
+
|
|
330
|
+
Voce e um TEAMMATE de implementacao do Codexa Workflow.
|
|
331
|
+
Voce NAO e o orquestrador. Voce NAO coordena. Voce EXECUTA tasks.
|
|
332
|
+
Dominio: ${domain}
|
|
333
|
+
|
|
334
|
+
## FEATURE
|
|
335
|
+
|
|
336
|
+
${spec.name}
|
|
337
|
+
|
|
338
|
+
## SUAS TASKS
|
|
339
|
+
|
|
340
|
+
${taskList}
|
|
341
|
+
|
|
342
|
+
## INSTRUCOES
|
|
343
|
+
|
|
344
|
+
Para CADA task atribuida a voce, execute na ordem:
|
|
345
|
+
|
|
346
|
+
### 1. Iniciar Task
|
|
347
|
+
\`\`\`bash
|
|
348
|
+
codexa task start <TASK_ID> --json
|
|
349
|
+
\`\`\`
|
|
350
|
+
Leia o \`subagentContext\` e \`context\` retornados. Estes sao suas instrucoes de implementacao.
|
|
351
|
+
|
|
352
|
+
### 2. Implementar
|
|
353
|
+
Use \`Read\`, \`Write\`, \`Edit\` para criar/modificar os arquivos listados.
|
|
354
|
+
|
|
355
|
+
**Regras de implementacao**:
|
|
356
|
+
- Siga os standards REQUIRED recebidos no contexto
|
|
357
|
+
- A cada 3 arquivos modificados, verifique blockers:
|
|
358
|
+
\`\`\`bash
|
|
359
|
+
codexa knowledge list --severity critical --unread
|
|
360
|
+
\`\`\`
|
|
361
|
+
- Se encontrar blocker critico: envie \`message\` ao lead explicando e PARE
|
|
362
|
+
|
|
363
|
+
### 3. Completar Task
|
|
364
|
+
\`\`\`bash
|
|
365
|
+
codexa task done <TASK_ID> --output '{"status":"completed","summary":"descricao do que foi feito","files_created":["..."],"files_modified":["..."],"reasoning":{"approach":"como abordou o problema (min 20 chars)"}}'
|
|
366
|
+
\`\`\`
|
|
367
|
+
|
|
368
|
+
### 4. Comunicar
|
|
369
|
+
Apos completar cada task, comunique via Agent Teams messaging (nativo):
|
|
370
|
+
- **Mensagem ao lead**: Use a ferramenta \`message\` para enviar resumo da task completada ao lead
|
|
371
|
+
- **Mensagem a outro teammate**: Use a ferramenta \`message\` para enviar diretamente ao teammate afetado
|
|
372
|
+
- **Persistir knowledge**: Para discoveries relevantes alem desta sessao:
|
|
373
|
+
\`\`\`bash
|
|
374
|
+
codexa knowledge add --content "DISCOVERY: descricao" --category discovery --severity info
|
|
375
|
+
\`\`\`
|
|
376
|
+
|
|
377
|
+
> **IMPORTANTE**: Use \`message\` (nativo Agent Teams) para comunicacao entre sessoes.
|
|
378
|
+
> Use \`codexa knowledge add\` (CLI) para persistir informacao no SQLite para futuras tasks.
|
|
379
|
+
> Ambos sao complementares — messaging e instantaneo, knowledge e persistente.
|
|
380
|
+
|
|
381
|
+
### 5. Proxima Task
|
|
382
|
+
Apos completar, prossiga para a proxima task da sua lista.
|
|
383
|
+
Se todas suas tasks estao done, envie mensagem ao lead via \`message\` informando conclusao.
|
|
384
|
+
|
|
385
|
+
## TASK LIST — REGRA CRITICA
|
|
386
|
+
|
|
387
|
+
Existem DUAS task lists neste ambiente:
|
|
388
|
+
1. **Codexa tasks** (SQLite, via CLI): Esta e a source of truth. Use \`codexa task start/done\`.
|
|
389
|
+
2. **Task list nativa** (Agent Teams): Usada APENAS pelo lead para coordenacao.
|
|
390
|
+
|
|
391
|
+
**Voce como teammate**: Use SOMENTE Codexa tasks (\`codexa task start\`, \`codexa task done\`).
|
|
392
|
+
NAO interaja com a task list nativa do Agent Teams — o lead gerencia ela.
|
|
393
|
+
|
|
394
|
+
## CONTEXTO ON-DEMAND
|
|
395
|
+
|
|
396
|
+
Se precisar de mais contexto alem do minimal:
|
|
397
|
+
\`\`\`bash
|
|
398
|
+
codexa context detail standards # Regras do projeto
|
|
399
|
+
codexa context detail decisions # Decisoes anteriores
|
|
400
|
+
codexa context detail patterns # Patterns de codigo
|
|
401
|
+
codexa context detail knowledge # Knowledge de outras tasks
|
|
402
|
+
codexa context detail architecture # Analise arquitetural
|
|
403
|
+
\`\`\`
|
|
404
|
+
|
|
405
|
+
## REGRAS ABSOLUTAS
|
|
406
|
+
|
|
407
|
+
1. SEMPRE use \`codexa task start\` ANTES de implementar (gates de qualidade)
|
|
408
|
+
2. SEMPRE use \`codexa task done --output\` APOS implementar (gates enforced)
|
|
409
|
+
3. NUNCA modifique arquivos de tasks de outros teammates
|
|
410
|
+
4. SEMPRE inclua \`reasoning.approach\` no retorno (minimo 20 chars — Gate 4.4)
|
|
411
|
+
5. Se bloqueado: envie \`message\` ao lead com contexto completo
|
|
412
|
+
6. Registre discoveries: \`codexa knowledge add\` (persistente) + \`message\` ao afetado (instantaneo)
|
|
413
|
+
7. NAO tente coordenar outros teammates — isso e papel do lead
|
|
414
|
+
8. Use SOMENTE Codexa tasks (CLI) — IGNORE a task list nativa do Agent Teams
|
|
415
|
+
9. Comunicacao entre sessoes: SEMPRE via ferramentas \`message\`/\`broadcast\` do Agent Teams`;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ─────────────────────────────────────────────────────────────────
|
|
419
|
+
// Spawn Prompts: REV
|
|
420
|
+
// ─────────────────────────────────────────────────────────────────
|
|
421
|
+
|
|
422
|
+
export function buildRevSpawnPrompt(spec: any, lens: string, artifactPaths: string[]): string {
|
|
423
|
+
const lensDescriptions: Record<string, string> = {
|
|
424
|
+
security: "SEGURANCA: OWASP Top 10 (injection, XSS, SSRF, CSRF), autenticacao/autorizacao (JWT, sessions, RBAC), secrets hardcoded, dependencias com vulnerabilidades, sanitizacao de input, file access, HTTP headers",
|
|
425
|
+
performance: "PERFORMANCE: N+1 queries, SELECT * sem necessidade, memory leaks, falta de memoizacao, queries sem index, renderizacoes desnecessarias (React), bundle size, lazy loading ausente, cache strategies",
|
|
426
|
+
standards: "STANDARDS E QUALIDADE: Conformidade com standards REQUIRED do projeto, DRY (utilities duplicadas), naming conventions, patterns do projeto seguidos, TypeScript types (sem 'any' injustificado), cobertura de testes, tratamento de erros",
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
return `## IDENTIDADE
|
|
430
|
+
|
|
431
|
+
Voce e um TEAMMATE revisor do Codexa Workflow.
|
|
432
|
+
Sua lente de analise: **${lens.toUpperCase()}**
|
|
433
|
+
Voce NAO modifica codigo. Voce ANALISA e REPORTA.
|
|
434
|
+
|
|
435
|
+
## FEATURE REVISADA
|
|
436
|
+
|
|
437
|
+
${spec.name}
|
|
438
|
+
|
|
439
|
+
## SUA LENTE
|
|
440
|
+
|
|
441
|
+
${lensDescriptions[lens] || lens}
|
|
442
|
+
|
|
443
|
+
## ARTEFATOS PARA REVISAO
|
|
444
|
+
|
|
445
|
+
${artifactPaths.map((p) => `- ${p}`).join("\n")}
|
|
446
|
+
|
|
447
|
+
## INSTRUCOES
|
|
448
|
+
|
|
449
|
+
### 1. Obter Contexto
|
|
450
|
+
\`\`\`bash
|
|
451
|
+
codexa review start --json
|
|
452
|
+
codexa context detail standards
|
|
453
|
+
\`\`\`
|
|
454
|
+
|
|
455
|
+
### 2. Ler Artefatos
|
|
456
|
+
Leia CADA arquivo listado acima usando a ferramenta Read.
|
|
457
|
+
|
|
458
|
+
### 3. Analisar com Sua Lente
|
|
459
|
+
Aplique APENAS sua lente (${lens}). NAO repita analises de outras lentes.
|
|
460
|
+
Para cada arquivo, identifique problemas por severidade.
|
|
461
|
+
|
|
462
|
+
### 4. Enviar Findings ao Lead
|
|
463
|
+
Use a ferramenta \`message\` (nativa do Agent Teams) para enviar ao lead no formato:
|
|
464
|
+
|
|
465
|
+
\`\`\`
|
|
466
|
+
## [${lens.toUpperCase()}] Review — ${spec.name}
|
|
467
|
+
|
|
468
|
+
### Criticos (bloqueiam aprovacao)
|
|
469
|
+
- [arquivo:linha] Problema. Remediacao sugerida.
|
|
470
|
+
|
|
471
|
+
### Altos (recomenda bloqueio)
|
|
472
|
+
- [arquivo:linha] Problema.
|
|
473
|
+
|
|
474
|
+
### Medios (warning)
|
|
475
|
+
- [arquivo:linha] Observacao.
|
|
476
|
+
|
|
477
|
+
### Baixos (sugestao)
|
|
478
|
+
- [arquivo:linha] Melhoria opcional.
|
|
479
|
+
|
|
480
|
+
### Resultado: APROVADO | REPROVADO | RESSALVAS
|
|
481
|
+
Justificativa: ...
|
|
482
|
+
\`\`\`
|
|
483
|
+
|
|
484
|
+
### 5. Registrar Knowledge
|
|
485
|
+
Para cada finding CRITICO ou ALTO:
|
|
486
|
+
\`\`\`bash
|
|
487
|
+
codexa knowledge add --content "REVIEW [${lens}]: problema em arquivo:linha" --category discovery --severity warning
|
|
488
|
+
\`\`\`
|
|
489
|
+
|
|
490
|
+
## COMUNICACAO
|
|
491
|
+
|
|
492
|
+
- **Enviar findings ao lead**: Use a ferramenta \`message\` (nativa Agent Teams)
|
|
493
|
+
- **Persistir findings criticos**: Use \`codexa knowledge add\` (CLI) para SQLite
|
|
494
|
+
- NAO use a task list nativa do Agent Teams — apenas o lead gerencia ela
|
|
495
|
+
|
|
496
|
+
## REGRAS
|
|
497
|
+
|
|
498
|
+
1. NAO modifique nenhum arquivo
|
|
499
|
+
2. Analise APENAS com sua lente (${lens})
|
|
500
|
+
3. Seja ESPECIFICO: arquivo, linha, problema, sugestao de correcao
|
|
501
|
+
4. Envie TODOS os findings ao lead via ferramenta \`message\`
|
|
502
|
+
5. Registre findings criticos/altos via \`codexa knowledge add\` (persistencia SQLite)
|
|
503
|
+
6. IGNORE a task list nativa do Agent Teams`;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// ─────────────────────────────────────────────────────────────────
|
|
507
|
+
// Spawn Prompts: Architect
|
|
508
|
+
// ─────────────────────────────────────────────────────────────────
|
|
509
|
+
|
|
510
|
+
export function buildArchitectSpawnPrompt(analysis: any, stackSummary: any, role: string): string {
|
|
511
|
+
return `## IDENTIDADE
|
|
512
|
+
|
|
513
|
+
Voce e o ARCHITECT ${role.toUpperCase()} do Codexa Workflow.
|
|
514
|
+
Voce propoe UMA abordagem INDEPENDENTE para o problema.
|
|
515
|
+
NAO consulte propostas de outros architects antes de formular a sua.
|
|
516
|
+
|
|
517
|
+
## PROBLEMA
|
|
518
|
+
|
|
519
|
+
${analysis.name}
|
|
520
|
+
|
|
521
|
+
## STACK ATUAL
|
|
522
|
+
|
|
523
|
+
${JSON.stringify(stackSummary, null, 2)}
|
|
524
|
+
|
|
525
|
+
## INSTRUCOES
|
|
526
|
+
|
|
527
|
+
### 1. Explorar Codebase
|
|
528
|
+
Use grepai para pesquisa semantica:
|
|
529
|
+
\`\`\`bash
|
|
530
|
+
grepai search "architecture layers and boundaries" --json --compact
|
|
531
|
+
grepai search "integration points for: ${analysis.name}" --json --compact
|
|
532
|
+
\`\`\`
|
|
533
|
+
|
|
534
|
+
Tambem use \`grepai trace\` para entender call graphs.
|
|
535
|
+
|
|
536
|
+
### 2. Contextualizar
|
|
537
|
+
\`\`\`bash
|
|
538
|
+
codexa context detail standards
|
|
539
|
+
codexa context detail architecture
|
|
540
|
+
codexa context detail patterns
|
|
541
|
+
\`\`\`
|
|
542
|
+
|
|
543
|
+
### 3. Propor Abordagem
|
|
544
|
+
|
|
545
|
+
Crie sua proposta seguindo os 8 headers OBRIGATORIOS:
|
|
546
|
+
|
|
547
|
+
1. **## Contexto e Entendimento** — O que voce entendeu do problema
|
|
548
|
+
2. **## Stack e Arquitetura Atual** — Estado atual do sistema
|
|
549
|
+
3. **## Solucao Proposta** — SUA abordagem unica com justificativa
|
|
550
|
+
4. **## Diagramas** — Minimo 2 diagramas Mermaid (arquitetura + fluxo)
|
|
551
|
+
5. **## Baby Steps** — Passos atomicos (1-3 arquivos cada), formato:
|
|
552
|
+
### N. Nome
|
|
553
|
+
**O que**: descricao
|
|
554
|
+
**Por que**: justificativa
|
|
555
|
+
**Resultado**: output esperado
|
|
556
|
+
**Arquivos**: lista
|
|
557
|
+
**Agente**: backend|frontend|database|testing|general
|
|
558
|
+
**Depende de**: N (ou nenhum)
|
|
559
|
+
6. **## Riscos e Mitigacoes** — Trade-offs explicitos
|
|
560
|
+
7. **## Alternativas Descartadas** — O que voce considerou e descartou
|
|
561
|
+
8. **## Decisoes Arquiteturais** — ADRs (Architecture Decision Records)
|
|
562
|
+
|
|
563
|
+
### 4. Enviar ao Lead
|
|
564
|
+
Use a ferramenta \`message\` (nativa Agent Teams) para enviar proposta completa ao lead.
|
|
565
|
+
|
|
566
|
+
### 5. Responder Criticas
|
|
567
|
+
Voce recebera criticas do devil's advocate via \`message\` (entrega automatica).
|
|
568
|
+
- Responda via \`message\` ao devil's advocate com justificativas tecnicas
|
|
569
|
+
- Reconheca pontos fracos legitimos
|
|
570
|
+
- Proponha ajustes se necessario
|
|
571
|
+
- Envie versao revisada ao lead via \`message\`
|
|
572
|
+
|
|
573
|
+
## COMUNICACAO
|
|
574
|
+
|
|
575
|
+
- **Proposta ao lead**: ferramenta \`message\` (nativa Agent Teams)
|
|
576
|
+
- **Resposta a criticas**: ferramenta \`message\` ao devil's advocate
|
|
577
|
+
- **NAO** leia arquivos criados por outros architects (independencia)
|
|
578
|
+
- **NAO** use a task list nativa do Agent Teams
|
|
579
|
+
|
|
580
|
+
## REGRAS
|
|
581
|
+
|
|
582
|
+
1. Proposta INDEPENDENTE — nao leia propostas de outros antes
|
|
583
|
+
2. NUNCA escreva codigo de implementacao
|
|
584
|
+
3. Minimo 2 diagramas Mermaid
|
|
585
|
+
4. Baby steps atomicos (1-3 arquivos cada)
|
|
586
|
+
5. Trade-offs EXPLICITOS para cada decisao
|
|
587
|
+
6. Considere escalabilidade, manutenibilidade, seguranca
|
|
588
|
+
7. Comunicacao SOMENTE via ferramenta \`message\` do Agent Teams`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// ─────────────────────────────────────────────────────────────────
|
|
592
|
+
// Spawn Prompts: Devil's Advocate
|
|
593
|
+
// ─────────────────────────────────────────────────────────────────
|
|
594
|
+
|
|
595
|
+
export function buildDevilAdvocatePrompt(analysis: any): string {
|
|
596
|
+
return `## IDENTIDADE
|
|
597
|
+
|
|
598
|
+
Voce e o DEVIL'S ADVOCATE do Codexa Workflow.
|
|
599
|
+
Seu papel e DESAFIAR propostas arquiteturais, encontrando pontos fracos,
|
|
600
|
+
riscos nao considerados, e alternativas melhores.
|
|
601
|
+
|
|
602
|
+
## PROBLEMA EM ANALISE
|
|
603
|
+
|
|
604
|
+
${analysis.name}
|
|
605
|
+
|
|
606
|
+
## INSTRUCOES
|
|
607
|
+
|
|
608
|
+
### 1. Aguardar Propostas
|
|
609
|
+
Propostas dos architects (alpha e beta) serao entregues automaticamente via
|
|
610
|
+
o sistema de messaging do Agent Teams. Voce recebera as mensagens sem precisar
|
|
611
|
+
fazer polling — o Agent Teams entrega mensagens automaticamente na sua sessao.
|
|
612
|
+
Aguarde ate receber AMBAS as propostas antes de iniciar a critica.
|
|
613
|
+
|
|
614
|
+
### 2. Analisar Criticamente CADA Proposta
|
|
615
|
+
|
|
616
|
+
Para cada proposta, avalie:
|
|
617
|
+
- **Viabilidade**: A solucao e realista para o contexto?
|
|
618
|
+
- **Escalabilidade**: Funciona com 10x mais dados/usuarios?
|
|
619
|
+
- **Manutenibilidade**: Outro dev entende em 6 meses?
|
|
620
|
+
- **Seguranca**: Ha vetores de ataque nao considerados?
|
|
621
|
+
- **Complexidade**: E a solucao mais simples possivel?
|
|
622
|
+
- **Trade-offs ocultos**: Que custos nao foram mencionados?
|
|
623
|
+
- **Baby steps**: Sao realmente atomicos? Dependencias corretas?
|
|
624
|
+
|
|
625
|
+
### 3. Enviar Criticas ao Lead
|
|
626
|
+
|
|
627
|
+
Para CADA proposta, use a ferramenta \`message\` para enviar critica estruturada ao lead:
|
|
628
|
+
|
|
629
|
+
\`\`\`
|
|
630
|
+
## Critica: Proposta [ALPHA/BETA]
|
|
631
|
+
|
|
632
|
+
### Pontos Fortes
|
|
633
|
+
- ...
|
|
634
|
+
|
|
635
|
+
### Pontos Fracos
|
|
636
|
+
- ...
|
|
637
|
+
|
|
638
|
+
### Riscos Nao Considerados
|
|
639
|
+
- ...
|
|
640
|
+
|
|
641
|
+
### Perguntas para o Architect
|
|
642
|
+
- ...
|
|
643
|
+
|
|
644
|
+
### Veredito: FORTE | VIAVEL | FRACO
|
|
645
|
+
Justificativa: ...
|
|
646
|
+
\`\`\`
|
|
647
|
+
|
|
648
|
+
### 4. Enviar Criticas aos Architects
|
|
649
|
+
|
|
650
|
+
Apos criticar cada proposta, envie tambem via \`message\` ao architect correspondente
|
|
651
|
+
para que ele possa defender/ajustar sua proposta.
|
|
652
|
+
|
|
653
|
+
### 5. Recomendar ao Lead
|
|
654
|
+
|
|
655
|
+
Apos criticar ambas e receber defesas, envie recomendacao final ao lead via \`message\`:
|
|
656
|
+
- Qual proposta e mais robusta e por que
|
|
657
|
+
- Sugestoes de melhoria combinando elementos de ambas
|
|
658
|
+
- Riscos que persistem independente da escolha
|
|
659
|
+
|
|
660
|
+
## COMUNICACAO
|
|
661
|
+
|
|
662
|
+
- **Receber propostas**: Automatico via Agent Teams messaging (sem polling)
|
|
663
|
+
- **Enviar criticas ao lead**: ferramenta \`message\`
|
|
664
|
+
- **Enviar criticas aos architects**: ferramenta \`message\` direta ao architect
|
|
665
|
+
- **NAO** use a task list nativa do Agent Teams
|
|
666
|
+
|
|
667
|
+
## REGRAS
|
|
668
|
+
|
|
669
|
+
1. Seja JUSTO — critique com fundamento, nao por criticar
|
|
670
|
+
2. NAO proponha sua propria solucao — apenas critique
|
|
671
|
+
3. Base criticas em principios de engenharia (SOLID, KISS, YAGNI)
|
|
672
|
+
4. Considere o contexto real do projeto (stack, team size, constraints)
|
|
673
|
+
5. Comunicacao SOMENTE via ferramenta \`message\` do Agent Teams
|
|
674
|
+
6. IGNORE a task list nativa do Agent Teams`;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// ─────────────────────────────────────────────────────────────────
|
|
678
|
+
// Output Formatting
|
|
679
|
+
// ─────────────────────────────────────────────────────────────────
|
|
680
|
+
|
|
681
|
+
function printTeamSuggestion(result: TeamSuggestion): void {
|
|
682
|
+
console.log(`\n${"─".repeat(50)}`);
|
|
683
|
+
console.log(`Agent Teams - Sugestao`);
|
|
684
|
+
console.log(`${"─".repeat(50)}`);
|
|
685
|
+
|
|
686
|
+
console.log(` Recomendado: ${result.recommended ? "SIM" : "NAO"}`);
|
|
687
|
+
console.log(` Modo: ${result.mode}`);
|
|
688
|
+
console.log(` Env var: ${result.envVarSet ? "definida" : "NAO definida"}`);
|
|
689
|
+
console.log(` Motivo: ${result.reason}`);
|
|
690
|
+
|
|
691
|
+
if (result.teamConfig) {
|
|
692
|
+
const tc = result.teamConfig;
|
|
693
|
+
console.log(`\n Fase: ${tc.phase}`);
|
|
694
|
+
console.log(` Paralelismo: ${tc.estimatedParallelism}`);
|
|
695
|
+
console.log(` Teammates (${tc.teammates.length}):`);
|
|
696
|
+
for (const tm of tc.teammates) {
|
|
697
|
+
const taskInfo = tm.taskIds.length > 0 ? ` [tasks: ${tm.taskIds.join(",")}]` : "";
|
|
698
|
+
console.log(` - ${tm.role} (${tm.domain})${taskInfo}`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
console.log(`\n${"─".repeat(50)}\n`);
|
|
703
|
+
}
|