maestro-bundle 1.0.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 +91 -0
- package/package.json +25 -0
- package/src/cli.mjs +212 -0
- package/templates/bundle-ai-agents/.spec/constitution.md +33 -0
- package/templates/bundle-ai-agents/AGENTS.md +140 -0
- package/templates/bundle-ai-agents/skills/agent-orchestration/SKILL.md +132 -0
- package/templates/bundle-ai-agents/skills/api-design/SKILL.md +100 -0
- package/templates/bundle-ai-agents/skills/clean-architecture/SKILL.md +99 -0
- package/templates/bundle-ai-agents/skills/context-engineering/SKILL.md +98 -0
- package/templates/bundle-ai-agents/skills/database-modeling/SKILL.md +59 -0
- package/templates/bundle-ai-agents/skills/docker-containerization/SKILL.md +114 -0
- package/templates/bundle-ai-agents/skills/eval-testing/SKILL.md +115 -0
- package/templates/bundle-ai-agents/skills/memory-management/SKILL.md +106 -0
- package/templates/bundle-ai-agents/skills/prompt-engineering/SKILL.md +66 -0
- package/templates/bundle-ai-agents/skills/rag-pipeline/SKILL.md +128 -0
- package/templates/bundle-ai-agents/skills/testing-strategy/SKILL.md +95 -0
- package/templates/bundle-base/AGENTS.md +118 -0
- package/templates/bundle-base/skills/branch-strategy/SKILL.md +42 -0
- package/templates/bundle-base/skills/code-review/SKILL.md +54 -0
- package/templates/bundle-base/skills/commit-pattern/SKILL.md +58 -0
- package/templates/bundle-data-pipeline/.spec/constitution.md +32 -0
- package/templates/bundle-data-pipeline/AGENTS.md +115 -0
- package/templates/bundle-data-pipeline/skills/data-preprocessing/SKILL.md +75 -0
- package/templates/bundle-data-pipeline/skills/docker-containerization/SKILL.md +114 -0
- package/templates/bundle-data-pipeline/skills/feature-engineering/SKILL.md +76 -0
- package/templates/bundle-data-pipeline/skills/mlops-pipeline/SKILL.md +77 -0
- package/templates/bundle-data-pipeline/skills/model-training/SKILL.md +68 -0
- package/templates/bundle-data-pipeline/skills/rag-pipeline/SKILL.md +128 -0
- package/templates/bundle-frontend-spa/.spec/constitution.md +32 -0
- package/templates/bundle-frontend-spa/AGENTS.md +107 -0
- package/templates/bundle-frontend-spa/skills/authentication/SKILL.md +90 -0
- package/templates/bundle-frontend-spa/skills/component-design/SKILL.md +115 -0
- package/templates/bundle-frontend-spa/skills/e2e-testing/SKILL.md +101 -0
- package/templates/bundle-frontend-spa/skills/integration-api/SKILL.md +95 -0
- package/templates/bundle-frontend-spa/skills/react-patterns/SKILL.md +130 -0
- package/templates/bundle-frontend-spa/skills/responsive-layout/SKILL.md +65 -0
- package/templates/bundle-frontend-spa/skills/state-management/SKILL.md +86 -0
- package/templates/bundle-jhipster-microservices/.spec/constitution.md +37 -0
- package/templates/bundle-jhipster-microservices/AGENTS.md +307 -0
- package/templates/bundle-jhipster-microservices/skills/ci-cd-pipeline/SKILL.md +112 -0
- package/templates/bundle-jhipster-microservices/skills/clean-architecture/SKILL.md +99 -0
- package/templates/bundle-jhipster-microservices/skills/ddd-tactical/SKILL.md +138 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-angular/SKILL.md +97 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-docker-k8s/SKILL.md +183 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-entities/SKILL.md +87 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-gateway/SKILL.md +96 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-kafka/SKILL.md +145 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-registry/SKILL.md +83 -0
- package/templates/bundle-jhipster-microservices/skills/jhipster-service/SKILL.md +131 -0
- package/templates/bundle-jhipster-microservices/skills/testing-strategy/SKILL.md +95 -0
- package/templates/bundle-jhipster-monorepo/.spec/constitution.md +32 -0
- package/templates/bundle-jhipster-monorepo/AGENTS.md +227 -0
- package/templates/bundle-jhipster-monorepo/skills/clean-architecture/SKILL.md +99 -0
- package/templates/bundle-jhipster-monorepo/skills/ddd-tactical/SKILL.md +138 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-angular/SKILL.md +166 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-entities/SKILL.md +141 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-liquibase/SKILL.md +95 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-security/SKILL.md +89 -0
- package/templates/bundle-jhipster-monorepo/skills/jhipster-spring/SKILL.md +155 -0
- package/templates/bundle-jhipster-monorepo/skills/testing-strategy/SKILL.md +95 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# maestro-bundle
|
|
2
|
+
|
|
3
|
+
Um comando. Bundle instalado. Agente governado.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx maestro-bundle ai-agents
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Instala automaticamente:
|
|
10
|
+
- `AGENTS.md` na raiz (compatível com Cursor, Claude Code, Copilot, Windsurf, etc.)
|
|
11
|
+
- `skills/` com todas as skills do bundle
|
|
12
|
+
- `.spec/constitution.md` do GitHub Spec Kit
|
|
13
|
+
- `references/` com docs de referência
|
|
14
|
+
- Instala o GitHub Spec Kit se necessário
|
|
15
|
+
|
|
16
|
+
## Bundles disponíveis
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx maestro-bundle ai-agents # Python + LangChain + LangGraph + FastAPI
|
|
20
|
+
npx maestro-bundle jhipster-monorepo # Java 21 + Spring Boot + Angular + PostgreSQL
|
|
21
|
+
npx maestro-bundle jhipster-microservices # Java 21 + Spring Boot + Kafka + Consul + K8s
|
|
22
|
+
npx maestro-bundle data-pipeline # Python + Pandas + Scikit-learn + MLflow
|
|
23
|
+
npx maestro-bundle frontend-spa # React + TypeScript + Tailwind + Vite
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Uso
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Instalar no diretório atual
|
|
30
|
+
npx maestro-bundle ai-agents
|
|
31
|
+
|
|
32
|
+
# Instalar em outro diretório
|
|
33
|
+
npx maestro-bundle jhipster-monorepo ./meu-projeto
|
|
34
|
+
|
|
35
|
+
# Ver bundles disponíveis
|
|
36
|
+
npx maestro-bundle --help
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## O que acontece
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
$ npx maestro-bundle ai-agents
|
|
43
|
+
|
|
44
|
+
Instalando: Sistema Multi-Agente com AI
|
|
45
|
+
Destino: /home/user/meu-projeto
|
|
46
|
+
|
|
47
|
+
✔ Estrutura criada
|
|
48
|
+
✔ AGENTS.md instalado na raiz
|
|
49
|
+
✔ 14 skills instaladas
|
|
50
|
+
✔ .spec/constitution.md instalado
|
|
51
|
+
✔ References instalados
|
|
52
|
+
✔ Spec Kit já disponível
|
|
53
|
+
✔ Spec Kit inicializado
|
|
54
|
+
|
|
55
|
+
Pronto!
|
|
56
|
+
|
|
57
|
+
Arquivos instalados:
|
|
58
|
+
AGENTS.md Comportamento do agente (qualquer editor AI)
|
|
59
|
+
.spec/constitution.md Princípios do projeto (GitHub Spec Kit)
|
|
60
|
+
skills/ (14 skills) Capacidades do agente
|
|
61
|
+
references/ Documentos de referência
|
|
62
|
+
|
|
63
|
+
Próximos passos:
|
|
64
|
+
1. Abra o projeto no seu editor AI (Cursor, Claude Code, Copilot, etc.)
|
|
65
|
+
2. O agente já conhece os padrões do projeto
|
|
66
|
+
3. Para nova demanda: /speckit.specify
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Resultado no projeto
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
seu-projeto/
|
|
73
|
+
├── AGENTS.md # Lido por qualquer editor AI
|
|
74
|
+
├── .spec/
|
|
75
|
+
│ └── constitution.md # Princípios (GitHub Spec Kit)
|
|
76
|
+
├── skills/
|
|
77
|
+
│ ├── commit-pattern/SKILL.md # Do bundle-base
|
|
78
|
+
│ ├── code-review/SKILL.md # Do bundle-base
|
|
79
|
+
│ ├── rag-pipeline/SKILL.md # Do bundle escolhido
|
|
80
|
+
│ ├── agent-orchestration/SKILL.md
|
|
81
|
+
│ └── ...
|
|
82
|
+
├── references/
|
|
83
|
+
│ └── ...
|
|
84
|
+
└── src/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Compatibilidade
|
|
88
|
+
|
|
89
|
+
O `AGENTS.md` segue o padrão [agents.md](https://agents.md/) e funciona com 30+ editores AI.
|
|
90
|
+
|
|
91
|
+
O `.spec/` segue o padrão [GitHub Spec Kit](https://github.com/github/spec-kit) para SDD.
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "maestro-bundle",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Instala bundles de governança para projetos com AI agents. Um comando, tudo configurado.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"maestro-bundle": "./src/cli.mjs"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"ai",
|
|
11
|
+
"agents",
|
|
12
|
+
"governance",
|
|
13
|
+
"jhipster",
|
|
14
|
+
"langchain",
|
|
15
|
+
"spec-kit",
|
|
16
|
+
"sdd",
|
|
17
|
+
"agents-md"
|
|
18
|
+
],
|
|
19
|
+
"author": "Maestro",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"chalk": "^5.3.0",
|
|
23
|
+
"ora": "^8.0.1"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/cli.mjs
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync, cpSync, readdirSync, readFileSync } from "fs";
|
|
4
|
+
import { join, resolve, dirname } from "path";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import ora from "ora";
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
const BUNDLES = {
|
|
13
|
+
"ai-agents": {
|
|
14
|
+
name: "Sistema Multi-Agente com AI",
|
|
15
|
+
description: "Python + LangChain + LangGraph + FastAPI + pgvector",
|
|
16
|
+
},
|
|
17
|
+
"jhipster-monorepo": {
|
|
18
|
+
name: "JHipster Monorepo",
|
|
19
|
+
description: "Java 21 + Spring Boot + Angular + PostgreSQL + Liquibase",
|
|
20
|
+
},
|
|
21
|
+
"jhipster-microservices": {
|
|
22
|
+
name: "JHipster Microservices",
|
|
23
|
+
description: "Java 21 + Spring Boot + Angular + Kafka + Consul + K8s",
|
|
24
|
+
},
|
|
25
|
+
"data-pipeline": {
|
|
26
|
+
name: "Pipeline de Dados e ML",
|
|
27
|
+
description: "Python + Pandas + Scikit-learn + MLflow + Airflow",
|
|
28
|
+
},
|
|
29
|
+
"frontend-spa": {
|
|
30
|
+
name: "Frontend SPA",
|
|
31
|
+
description: "React + TypeScript + Tailwind + Vite",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function showHelp() {
|
|
36
|
+
console.log("");
|
|
37
|
+
console.log(chalk.bold(" maestro-bundle") + " — Instala bundles de governança para projetos com AI");
|
|
38
|
+
console.log("");
|
|
39
|
+
console.log(chalk.dim(" Uso:"));
|
|
40
|
+
console.log(` npx maestro-bundle ${chalk.green("<bundle>")} ${chalk.dim("[diretório]")}`);
|
|
41
|
+
console.log("");
|
|
42
|
+
console.log(chalk.dim(" Bundles disponíveis:"));
|
|
43
|
+
console.log("");
|
|
44
|
+
for (const [key, info] of Object.entries(BUNDLES)) {
|
|
45
|
+
console.log(` ${chalk.green(key.padEnd(26))} ${info.name}`);
|
|
46
|
+
console.log(` ${"".padEnd(26)} ${chalk.dim(info.description)}`);
|
|
47
|
+
console.log("");
|
|
48
|
+
}
|
|
49
|
+
console.log(chalk.dim(" Exemplos:"));
|
|
50
|
+
console.log(` npx maestro-bundle ai-agents`);
|
|
51
|
+
console.log(` npx maestro-bundle jhipster-monorepo ./meu-projeto`);
|
|
52
|
+
console.log(` npx maestro-bundle frontend-spa .`);
|
|
53
|
+
console.log("");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function countSkills(dir) {
|
|
57
|
+
if (!existsSync(dir)) return 0;
|
|
58
|
+
let count = 0;
|
|
59
|
+
for (const item of readdirSync(dir, { withFileTypes: true })) {
|
|
60
|
+
if (item.isDirectory()) {
|
|
61
|
+
const skillFile = join(dir, item.name, "SKILL.md");
|
|
62
|
+
if (existsSync(skillFile)) count++;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return count;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function main() {
|
|
69
|
+
const args = process.argv.slice(2);
|
|
70
|
+
|
|
71
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
72
|
+
showHelp();
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const bundleName = args[0];
|
|
77
|
+
const targetDir = resolve(args[1] || ".");
|
|
78
|
+
|
|
79
|
+
if (!BUNDLES[bundleName]) {
|
|
80
|
+
console.error(chalk.red(`\n Bundle "${bundleName}" não encontrado.\n`));
|
|
81
|
+
showHelp();
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const info = BUNDLES[bundleName];
|
|
86
|
+
const templatesDir = join(__dirname, "..", "templates");
|
|
87
|
+
const baseDir = join(templatesDir, "bundle-base");
|
|
88
|
+
const bundleDir = join(templatesDir, `bundle-${bundleName}`);
|
|
89
|
+
|
|
90
|
+
if (!existsSync(bundleDir)) {
|
|
91
|
+
console.error(chalk.red(`\n Templates do bundle "${bundleName}" não encontrados em ${bundleDir}\n`));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log("");
|
|
96
|
+
console.log(chalk.bold(` Instalando: ${chalk.green(info.name)}`));
|
|
97
|
+
console.log(chalk.dim(` Destino: ${targetDir}`));
|
|
98
|
+
console.log("");
|
|
99
|
+
|
|
100
|
+
// 1. Criar diretórios
|
|
101
|
+
let spinner = ora("Criando estrutura").start();
|
|
102
|
+
for (const dir of ["skills", ".spec", "references"]) {
|
|
103
|
+
mkdirSync(join(targetDir, dir), { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
spinner.succeed("Estrutura criada");
|
|
106
|
+
|
|
107
|
+
// 2. AGENTS.md (base + bundle concatenados)
|
|
108
|
+
spinner = ora("Instalando AGENTS.md").start();
|
|
109
|
+
let agentsMd = "";
|
|
110
|
+
const baseAgentsPath = join(baseDir, "AGENTS.md");
|
|
111
|
+
const bundleAgentsPath = join(bundleDir, "AGENTS.md");
|
|
112
|
+
|
|
113
|
+
if (existsSync(baseAgentsPath)) {
|
|
114
|
+
agentsMd += readFileSync(baseAgentsPath, "utf-8");
|
|
115
|
+
}
|
|
116
|
+
if (existsSync(bundleAgentsPath)) {
|
|
117
|
+
agentsMd += "\n\n---\n\n";
|
|
118
|
+
agentsMd += readFileSync(bundleAgentsPath, "utf-8");
|
|
119
|
+
}
|
|
120
|
+
writeFileSync(join(targetDir, "AGENTS.md"), agentsMd);
|
|
121
|
+
spinner.succeed("AGENTS.md instalado na raiz");
|
|
122
|
+
|
|
123
|
+
// 3. Skills (base + bundle)
|
|
124
|
+
spinner = ora("Instalando skills").start();
|
|
125
|
+
const skillsDir = join(targetDir, "skills");
|
|
126
|
+
if (existsSync(join(baseDir, "skills"))) {
|
|
127
|
+
cpSync(join(baseDir, "skills"), skillsDir, { recursive: true });
|
|
128
|
+
}
|
|
129
|
+
if (existsSync(join(bundleDir, "skills"))) {
|
|
130
|
+
cpSync(join(bundleDir, "skills"), skillsDir, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
const skillCount = countSkills(skillsDir);
|
|
133
|
+
spinner.succeed(`${skillCount} skills instaladas`);
|
|
134
|
+
|
|
135
|
+
// 4. .spec/constitution.md
|
|
136
|
+
spinner = ora("Instalando constitution (Spec Kit)").start();
|
|
137
|
+
if (existsSync(join(bundleDir, ".spec"))) {
|
|
138
|
+
cpSync(join(bundleDir, ".spec"), join(targetDir, ".spec"), { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
spinner.succeed(".spec/constitution.md instalado");
|
|
141
|
+
|
|
142
|
+
// 5. References
|
|
143
|
+
spinner = ora("Instalando references").start();
|
|
144
|
+
if (existsSync(join(bundleDir, "references"))) {
|
|
145
|
+
cpSync(join(bundleDir, "references"), join(targetDir, "references"), { recursive: true });
|
|
146
|
+
}
|
|
147
|
+
spinner.succeed("References instalados");
|
|
148
|
+
|
|
149
|
+
// 6. GitHub Spec Kit
|
|
150
|
+
spinner = ora("Verificando GitHub Spec Kit").start();
|
|
151
|
+
let specKitInstalled = false;
|
|
152
|
+
try {
|
|
153
|
+
execSync("specify --version", { stdio: "ignore" });
|
|
154
|
+
specKitInstalled = true;
|
|
155
|
+
spinner.succeed("Spec Kit já disponível");
|
|
156
|
+
} catch {
|
|
157
|
+
spinner.info("Spec Kit não encontrado");
|
|
158
|
+
spinner = ora("Instalando GitHub Spec Kit...").start();
|
|
159
|
+
try {
|
|
160
|
+
execSync(
|
|
161
|
+
"uv tool install specify-cli --from git+https://github.com/github/spec-kit.git",
|
|
162
|
+
{ stdio: "ignore", timeout: 120000 }
|
|
163
|
+
);
|
|
164
|
+
specKitInstalled = true;
|
|
165
|
+
spinner.succeed("Spec Kit instalado");
|
|
166
|
+
} catch {
|
|
167
|
+
try {
|
|
168
|
+
execSync(
|
|
169
|
+
"pip install specify-cli",
|
|
170
|
+
{ stdio: "ignore", timeout: 60000 }
|
|
171
|
+
);
|
|
172
|
+
specKitInstalled = true;
|
|
173
|
+
spinner.succeed("Spec Kit instalado via pip");
|
|
174
|
+
} catch {
|
|
175
|
+
spinner.warn("Instale o Spec Kit manualmente:");
|
|
176
|
+
console.log(chalk.dim(" uv tool install specify-cli --from git+https://github.com/github/spec-kit.git"));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 7. Inicializar Spec Kit
|
|
182
|
+
if (specKitInstalled) {
|
|
183
|
+
spinner = ora("Inicializando Spec Kit").start();
|
|
184
|
+
try {
|
|
185
|
+
execSync(`specify init "${targetDir}"`, { stdio: "ignore", timeout: 15000, cwd: targetDir });
|
|
186
|
+
spinner.succeed("Spec Kit inicializado");
|
|
187
|
+
} catch {
|
|
188
|
+
spinner.info("Execute 'specify init .' no diretório do projeto");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Done
|
|
193
|
+
console.log("");
|
|
194
|
+
console.log(chalk.green.bold(" Pronto!"));
|
|
195
|
+
console.log("");
|
|
196
|
+
console.log(" Arquivos instalados:");
|
|
197
|
+
console.log(` ${chalk.cyan("AGENTS.md")} Comportamento do agente (qualquer editor AI)`);
|
|
198
|
+
console.log(` ${chalk.cyan(".spec/constitution.md")} Princípios do projeto (GitHub Spec Kit)`);
|
|
199
|
+
console.log(` ${chalk.cyan(`skills/ (${skillCount} skills)`)} Capacidades do agente`);
|
|
200
|
+
console.log(` ${chalk.cyan("references/")} Documentos de referência`);
|
|
201
|
+
console.log("");
|
|
202
|
+
console.log(" Próximos passos:");
|
|
203
|
+
console.log(` 1. Abra o projeto no seu editor AI ${chalk.dim("(Cursor, Claude Code, Copilot, etc.)")}`);
|
|
204
|
+
console.log(" 2. O agente já conhece os padrões do projeto");
|
|
205
|
+
console.log(` 3. Para nova demanda: ${chalk.cyan("/speckit.specify")}`);
|
|
206
|
+
console.log("");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
main().catch((err) => {
|
|
210
|
+
console.error(chalk.red(`\n Erro: ${err.message}\n`));
|
|
211
|
+
process.exit(1);
|
|
212
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Constitution — Projeto de Agentes AI
|
|
2
|
+
|
|
3
|
+
## Princípios
|
|
4
|
+
|
|
5
|
+
1. **Spec primeiro, código depois** — Toda demanda passa pelo fluxo SDD antes de implementação
|
|
6
|
+
2. **Agente governado** — Todo agente segue seu AGENTS.md e skills, sem "vibing coding"
|
|
7
|
+
3. **Observável** — Toda execução de agente é rastreada no Langfuse
|
|
8
|
+
4. **Avaliável** — Todo agente tem evals com golden dataset antes de ir para produção
|
|
9
|
+
5. **Context-aware** — Gerenciar janela de contexto com as 4 estratégias (Write, Select, Compress, Isolate)
|
|
10
|
+
|
|
11
|
+
## Padrões de desenvolvimento
|
|
12
|
+
|
|
13
|
+
- Clean Architecture para separar domínio de infraestrutura
|
|
14
|
+
- Entidades ricas com comportamento (não anêmicas)
|
|
15
|
+
- Value Objects para validação
|
|
16
|
+
- Testes: >= 80% cobertura, evals para agentes
|
|
17
|
+
- Python 3.11+, type hints, Black + Ruff
|
|
18
|
+
|
|
19
|
+
## Padrões de agentes
|
|
20
|
+
|
|
21
|
+
- System prompts versionados, nunca hardcoded
|
|
22
|
+
- Tools com schemas Pydantic
|
|
23
|
+
- Human-in-the-loop para operações destrutivas
|
|
24
|
+
- Timeout e limite de iterações em loops
|
|
25
|
+
- Memória de longo prazo via LangGraph Store
|
|
26
|
+
|
|
27
|
+
## Padrões de qualidade
|
|
28
|
+
|
|
29
|
+
- Code review obrigatório
|
|
30
|
+
- Commits seguem Conventional Commits
|
|
31
|
+
- Branches seguem estratégia feature/fix/hotfix
|
|
32
|
+
- Nunca commitar secrets
|
|
33
|
+
- Rate limiting em todas as APIs
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Projeto: Sistema Multi-Agente com AI
|
|
2
|
+
|
|
3
|
+
Você está construindo um sistema de agentes AI com orquestração, RAG e execução autônoma de tarefas. O backend é Python com FastAPI, a orquestração usa LangChain + LangGraph, e a infra roda em containers.
|
|
4
|
+
|
|
5
|
+
## Specification-Driven Development (SDD)
|
|
6
|
+
|
|
7
|
+
Este projeto usa **GitHub Spec Kit** para governança. Antes de implementar qualquer demanda:
|
|
8
|
+
|
|
9
|
+
1. Rodar `/speckit.constitution` — se `.spec/constitution.md` não existir
|
|
10
|
+
2. Rodar `/speckit.specify` — descrever O QUE e POR QUÊ (não como)
|
|
11
|
+
3. Rodar `/speckit.plan` — arquitetura e decisões técnicas
|
|
12
|
+
4. Rodar `/speckit.tasks` — quebrar em tasks atômicas
|
|
13
|
+
5. Rodar `/speckit.implement` — executar as tasks
|
|
14
|
+
|
|
15
|
+
Nunca pular direto para código. Spec primeiro, código depois.
|
|
16
|
+
|
|
17
|
+
## References
|
|
18
|
+
|
|
19
|
+
Documentos de referência que o agente deve consultar quando necessário:
|
|
20
|
+
|
|
21
|
+
- `references/fastapi-patterns.md` — Padrões de endpoints FastAPI
|
|
22
|
+
- `references/langgraph-patterns.md` — Padrões de grafos LangGraph
|
|
23
|
+
- `references/rag-best-practices.md` — Melhores práticas de RAG
|
|
24
|
+
- `references/eval-framework.md` — Framework de avaliação de agentes
|
|
25
|
+
|
|
26
|
+
## Stack do projeto
|
|
27
|
+
|
|
28
|
+
- **Linguagem:** Python 3.11+
|
|
29
|
+
- **Agentes:** LangChain + LangGraph + Deep Agents
|
|
30
|
+
- **API:** FastAPI
|
|
31
|
+
- **Banco:** PostgreSQL (relacional + pgvector para RAG)
|
|
32
|
+
- **Cache/Filas:** Redis Streams
|
|
33
|
+
- **Embeddings:** text-embedding-3-large ou multilingual-e5-large
|
|
34
|
+
- **Observabilidade:** Langfuse (self-hosted)
|
|
35
|
+
- **Containers:** Docker + K3s
|
|
36
|
+
- **Testes:** Pytest + evals customizados
|
|
37
|
+
|
|
38
|
+
## Estrutura do projeto
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/
|
|
42
|
+
├── agents/ # Definição dos agentes
|
|
43
|
+
│ ├── orchestrator/
|
|
44
|
+
│ │ ├── agent.py # Deep Agent orquestrador
|
|
45
|
+
│ │ ├── state.py # AgentState do LangGraph
|
|
46
|
+
│ │ ├── nodes.py # Nós do grafo
|
|
47
|
+
│ │ ├── tools.py # Tools do agente
|
|
48
|
+
│ │ └── prompts.py # System prompts versionados
|
|
49
|
+
│ ├── frontend_agent/
|
|
50
|
+
│ ├── backend_agent/
|
|
51
|
+
│ └── devops_agent/
|
|
52
|
+
├── domain/ # Clean Architecture — regras de negócio
|
|
53
|
+
│ ├── entities/
|
|
54
|
+
│ ├── value_objects/
|
|
55
|
+
│ ├── events/
|
|
56
|
+
│ ├── services/
|
|
57
|
+
│ └── repositories/ # Interfaces (ports)
|
|
58
|
+
├── application/ # Use cases
|
|
59
|
+
│ ├── use_cases/
|
|
60
|
+
│ ├── dtos/
|
|
61
|
+
│ └── mappers/
|
|
62
|
+
├── infrastructure/ # Implementações (adapters)
|
|
63
|
+
│ ├── persistence/
|
|
64
|
+
│ ├── mcp/
|
|
65
|
+
│ ├── langfuse/
|
|
66
|
+
│ └── config/
|
|
67
|
+
├── rag/ # Pipeline de RAG
|
|
68
|
+
│ ├── ingest.py
|
|
69
|
+
│ ├── retriever.py
|
|
70
|
+
│ ├── embeddings.py
|
|
71
|
+
│ └── reranker.py
|
|
72
|
+
├── api/ # Endpoints REST + WebSocket
|
|
73
|
+
│ ├── controllers/
|
|
74
|
+
│ └── middlewares/
|
|
75
|
+
├── evals/ # Avaliação dos agentes
|
|
76
|
+
│ ├── golden_dataset.json
|
|
77
|
+
│ ├── evaluators.py
|
|
78
|
+
│ ├── run_evals.py
|
|
79
|
+
│ └── judges.py
|
|
80
|
+
└── memory/ # Memória longo prazo
|
|
81
|
+
├── store.py
|
|
82
|
+
└── checkpointer.py
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Padrões de código
|
|
86
|
+
|
|
87
|
+
- Máximo 500 linhas por arquivo, 20 linhas por função
|
|
88
|
+
- Type hints em funções públicas
|
|
89
|
+
- f-strings para interpolação
|
|
90
|
+
- Black + Ruff para formatação
|
|
91
|
+
- Nomes descritivos, sem abreviações
|
|
92
|
+
- Guard clauses em vez de ifs aninhados
|
|
93
|
+
- Tratar exceções com tipos específicos, nunca `except Exception` vazio
|
|
94
|
+
|
|
95
|
+
## Padrões de agentes
|
|
96
|
+
|
|
97
|
+
- Cada agente tem UMA responsabilidade
|
|
98
|
+
- System prompts versionados em `prompts.py`, nunca hardcoded
|
|
99
|
+
- Tools com nomes claros, descrições precisas e schemas Pydantic
|
|
100
|
+
- Timeout e limite de iterações em todo loop
|
|
101
|
+
- Human-in-the-loop para: merge, deploy, delete, operações destrutivas
|
|
102
|
+
- Traces no Langfuse para toda execução
|
|
103
|
+
- Eval com golden dataset antes de deploy
|
|
104
|
+
|
|
105
|
+
## Context Engineering
|
|
106
|
+
|
|
107
|
+
- **Write:** Este CLAUDE.md + skills por contexto
|
|
108
|
+
- **Select:** RAG para injetar contexto relevante ao agente
|
|
109
|
+
- **Compress:** Summarization de código longo antes de enviar
|
|
110
|
+
- **Isolate:** Cada agente com contexto isolado (worktree + janela separada)
|
|
111
|
+
|
|
112
|
+
## RAG
|
|
113
|
+
|
|
114
|
+
- RecursiveCharacterTextSplitter (chunk 1000, overlap 200)
|
|
115
|
+
- Metadados obrigatórios: source, doc_type, language, created_at
|
|
116
|
+
- Hybrid search: pgvector + ts_vector + RRF
|
|
117
|
+
- Re-ranking com cross-encoder no top-k
|
|
118
|
+
- Testar retrieval quality antes de ir para produção
|
|
119
|
+
|
|
120
|
+
## Git
|
|
121
|
+
|
|
122
|
+
- Commits: `feat(agents): adicionar roteamento condicional`
|
|
123
|
+
- Branches: `feature/<modulo>-<descricao>`
|
|
124
|
+
- Nunca commitar secrets, .env, API keys
|
|
125
|
+
- Worktrees isoladas por agente quando em execução paralela
|
|
126
|
+
|
|
127
|
+
## Testes
|
|
128
|
+
|
|
129
|
+
- Unitários: Value Objects, Entities, regras de domínio (>= 90%)
|
|
130
|
+
- Integração: Repositórios, APIs (>= 70%)
|
|
131
|
+
- Evals: Golden dataset + LLM-as-judge + rule-based (>= 80% score)
|
|
132
|
+
- Nome: `test_should_<resultado>_when_<condição>`
|
|
133
|
+
|
|
134
|
+
## Segurança
|
|
135
|
+
|
|
136
|
+
- Rate limiting em todas as APIs
|
|
137
|
+
- Guardrails contra prompt injection nos inputs
|
|
138
|
+
- JWT para autenticação, API keys para agentes
|
|
139
|
+
- HTTPS obrigatório
|
|
140
|
+
- Validar inputs nas fronteiras do sistema
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-orchestration
|
|
3
|
+
description: Criar sistemas multi-agente com LangGraph incluindo orquestrador, subagentes, roteamento e delegação. Use quando precisar coordenar múltiplos agentes, criar times de agentes, ou implementar orquestração com LangGraph.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Orquestração de Agentes
|
|
7
|
+
|
|
8
|
+
## Arquitetura Multi-Agente
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Orquestrador (LangGraph StateGraph)
|
|
12
|
+
├── Router Node → decide qual agente executar
|
|
13
|
+
├── Agent Frontend → executa tasks de frontend
|
|
14
|
+
├── Agent Backend → executa tasks de backend
|
|
15
|
+
├── Agent DevOps → executa tasks de infra
|
|
16
|
+
├── Validator Node → valida compliance com bundle
|
|
17
|
+
├── Human Review → interrupt para aprovação
|
|
18
|
+
└── Merger Node → mergea branches dos agentes
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## AgentState
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from typing import TypedDict, Annotated, Literal
|
|
25
|
+
from langgraph.graph.message import add_messages
|
|
26
|
+
|
|
27
|
+
class OrchestratorState(TypedDict):
|
|
28
|
+
messages: Annotated[list, add_messages]
|
|
29
|
+
demand: dict
|
|
30
|
+
task_plan: list[dict]
|
|
31
|
+
current_task_index: int
|
|
32
|
+
assigned_agents: dict[str, str] # task_id -> agent_type
|
|
33
|
+
branch_status: dict[str, str] # agent -> branch_name
|
|
34
|
+
compliance_results: list[dict]
|
|
35
|
+
needs_human_review: bool
|
|
36
|
+
final_status: str
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Grafo do Orquestrador
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from langgraph.graph import StateGraph, START, END
|
|
43
|
+
|
|
44
|
+
graph = StateGraph(OrchestratorState)
|
|
45
|
+
|
|
46
|
+
# Nós
|
|
47
|
+
graph.add_node("analyze_demand", analyze_demand_node)
|
|
48
|
+
graph.add_node("plan_tasks", plan_tasks_node)
|
|
49
|
+
graph.add_node("route_to_agent", route_to_agent_node)
|
|
50
|
+
graph.add_node("execute_agent", execute_agent_node)
|
|
51
|
+
graph.add_node("validate_compliance", validate_compliance_node)
|
|
52
|
+
graph.add_node("human_review", human_review_node)
|
|
53
|
+
graph.add_node("merge_work", merge_work_node)
|
|
54
|
+
|
|
55
|
+
# Edges
|
|
56
|
+
graph.add_edge(START, "analyze_demand")
|
|
57
|
+
graph.add_edge("analyze_demand", "plan_tasks")
|
|
58
|
+
graph.add_edge("plan_tasks", "route_to_agent")
|
|
59
|
+
graph.add_conditional_edges("route_to_agent", should_continue, {
|
|
60
|
+
"execute": "execute_agent",
|
|
61
|
+
"all_done": "validate_compliance"
|
|
62
|
+
})
|
|
63
|
+
graph.add_edge("execute_agent", "route_to_agent")
|
|
64
|
+
graph.add_conditional_edges("validate_compliance", needs_review, {
|
|
65
|
+
"review": "human_review",
|
|
66
|
+
"pass": "merge_work"
|
|
67
|
+
})
|
|
68
|
+
graph.add_edge("human_review", "merge_work")
|
|
69
|
+
graph.add_edge("merge_work", END)
|
|
70
|
+
|
|
71
|
+
app = graph.compile(checkpointer=PostgresSaver(conn))
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Delegação para subagentes
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
async def execute_agent_node(state: OrchestratorState):
|
|
78
|
+
task = state["task_plan"][state["current_task_index"]]
|
|
79
|
+
agent_type = state["assigned_agents"][task["id"]]
|
|
80
|
+
|
|
81
|
+
# Cada agente tem seu próprio grafo/tools
|
|
82
|
+
agent = agent_registry.get(agent_type)
|
|
83
|
+
result = await agent.ainvoke({
|
|
84
|
+
"task": task,
|
|
85
|
+
"bundle": bundles[agent_type],
|
|
86
|
+
"worktree": worktrees[agent_type]
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
"current_task_index": state["current_task_index"] + 1,
|
|
91
|
+
"branch_status": {
|
|
92
|
+
**state["branch_status"],
|
|
93
|
+
agent_type: result["branch_name"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Roteamento inteligente
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
def route_to_agent(state: OrchestratorState) -> dict:
|
|
102
|
+
"""Decide qual tipo de agente executar baseado na task"""
|
|
103
|
+
task = state["task_plan"][state["current_task_index"]]
|
|
104
|
+
|
|
105
|
+
routing_map = {
|
|
106
|
+
"frontend": ["ui", "componente", "tela", "react", "css"],
|
|
107
|
+
"backend": ["api", "endpoint", "banco", "service", "entity"],
|
|
108
|
+
"devops": ["deploy", "pipeline", "docker", "k8s", "ci"],
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for agent_type, keywords in routing_map.items():
|
|
112
|
+
if any(kw in task["description"].lower() for kw in keywords):
|
|
113
|
+
return {"assigned_agents": {task["id"]: agent_type}}
|
|
114
|
+
|
|
115
|
+
# Fallback: usar LLM para decidir
|
|
116
|
+
return {"assigned_agents": {task["id"]: llm_route(task)}}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Human-in-the-loop
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from langgraph.types import interrupt
|
|
123
|
+
|
|
124
|
+
def human_review_node(state: OrchestratorState):
|
|
125
|
+
approval = interrupt({
|
|
126
|
+
"type": "merge_approval",
|
|
127
|
+
"branches": state["branch_status"],
|
|
128
|
+
"compliance": state["compliance_results"],
|
|
129
|
+
"message": "Aprovar merge dos branches?"
|
|
130
|
+
})
|
|
131
|
+
return {"needs_human_review": False, "final_status": approval["decision"]}
|
|
132
|
+
```
|