@maestro-ai/mcp-server 2.6.1 → 5.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/dist/content/.version.json +16 -0
- package/dist/data/project-templates.d.ts +37 -0
- package/dist/data/project-templates.d.ts.map +1 -0
- package/dist/data/project-templates.js +208 -0
- package/dist/data/project-templates.js.map +1 -0
- package/dist/errors/index.d.ts +84 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +158 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/flows/onboarding-orchestrator.d.ts.map +1 -1
- package/dist/flows/onboarding-orchestrator.js +126 -91
- package/dist/flows/onboarding-orchestrator.js.map +1 -1
- package/dist/gates/validator.d.ts +2 -1
- package/dist/gates/validator.d.ts.map +1 -1
- package/dist/gates/validator.js +33 -2
- package/dist/gates/validator.js.map +1 -1
- package/dist/index.js +19 -164
- package/dist/index.js.map +1 -1
- package/dist/middleware/flow-engine.middleware.d.ts +14 -0
- package/dist/middleware/flow-engine.middleware.d.ts.map +1 -0
- package/dist/middleware/flow-engine.middleware.js +51 -0
- package/dist/middleware/flow-engine.middleware.js.map +1 -0
- package/dist/middleware/index.d.ts +36 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +45 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/persistence.middleware.d.ts +14 -0
- package/dist/middleware/persistence.middleware.d.ts.map +1 -0
- package/dist/middleware/persistence.middleware.js +55 -0
- package/dist/middleware/persistence.middleware.js.map +1 -0
- package/dist/middleware/skill-injection.middleware.d.ts +15 -0
- package/dist/middleware/skill-injection.middleware.d.ts.map +1 -0
- package/dist/middleware/skill-injection.middleware.js +63 -0
- package/dist/middleware/skill-injection.middleware.js.map +1 -0
- package/dist/middleware/state-loader.middleware.d.ts +13 -0
- package/dist/middleware/state-loader.middleware.d.ts.map +1 -0
- package/dist/middleware/state-loader.middleware.js +36 -0
- package/dist/middleware/state-loader.middleware.js.map +1 -0
- package/dist/router.d.ts +46 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +441 -0
- package/dist/router.js.map +1 -0
- package/dist/services/content-resolver.service.d.ts +96 -0
- package/dist/services/content-resolver.service.d.ts.map +1 -0
- package/dist/services/content-resolver.service.js +280 -0
- package/dist/services/content-resolver.service.js.map +1 -0
- package/dist/services/flow-engine.d.ts +82 -0
- package/dist/services/flow-engine.d.ts.map +1 -0
- package/dist/services/flow-engine.js +270 -0
- package/dist/services/flow-engine.js.map +1 -0
- package/dist/services/onboarding.service.d.ts +20 -0
- package/dist/services/onboarding.service.d.ts.map +1 -0
- package/dist/services/onboarding.service.js +49 -0
- package/dist/services/onboarding.service.js.map +1 -0
- package/dist/services/skill-loader.service.d.ts +81 -0
- package/dist/services/skill-loader.service.d.ts.map +1 -0
- package/dist/services/skill-loader.service.js +321 -0
- package/dist/services/skill-loader.service.js.map +1 -0
- package/dist/services/specialist.service.d.ts +20 -0
- package/dist/services/specialist.service.d.ts.map +1 -0
- package/dist/services/specialist.service.js +115 -0
- package/dist/services/specialist.service.js.map +1 -0
- package/dist/services/state.service.d.ts +59 -0
- package/dist/services/state.service.d.ts.map +1 -0
- package/dist/services/state.service.js +131 -0
- package/dist/services/state.service.js.map +1 -0
- package/dist/stdio.js +329 -437
- package/dist/stdio.js.map +1 -1
- package/dist/tests/content-resolver.test.d.ts +5 -0
- package/dist/tests/content-resolver.test.d.ts.map +1 -0
- package/dist/tests/content-resolver.test.js +157 -0
- package/dist/tests/content-resolver.test.js.map +1 -0
- package/dist/tests/middleware.test.d.ts +5 -0
- package/dist/tests/middleware.test.d.ts.map +1 -0
- package/dist/tests/middleware.test.js +228 -0
- package/dist/tests/middleware.test.js.map +1 -0
- package/dist/tests/skill-loader.test.d.ts +5 -0
- package/dist/tests/skill-loader.test.d.ts.map +1 -0
- package/dist/tests/skill-loader.test.js +242 -0
- package/dist/tests/skill-loader.test.js.map +1 -0
- package/dist/tools/aprovar-gate.d.ts.map +1 -1
- package/dist/tools/aprovar-gate.js +35 -0
- package/dist/tools/aprovar-gate.js.map +1 -1
- package/dist/tools/brainstorm.d.ts.map +1 -1
- package/dist/tools/brainstorm.js +90 -49
- package/dist/tools/brainstorm.js.map +1 -1
- package/dist/tools/classificar.d.ts.map +1 -1
- package/dist/tools/classificar.js +20 -1
- package/dist/tools/classificar.js.map +1 -1
- package/dist/tools/confirmar-classificacao.d.ts.map +1 -1
- package/dist/tools/confirmar-classificacao.js +20 -1
- package/dist/tools/confirmar-classificacao.js.map +1 -1
- package/dist/tools/consolidated/analisar.d.ts +56 -0
- package/dist/tools/consolidated/analisar.d.ts.map +1 -0
- package/dist/tools/consolidated/analisar.js +96 -0
- package/dist/tools/consolidated/analisar.js.map +1 -0
- package/dist/tools/consolidated/avancar.d.ts +67 -0
- package/dist/tools/consolidated/avancar.d.ts.map +1 -0
- package/dist/tools/consolidated/avancar.js +132 -0
- package/dist/tools/consolidated/avancar.js.map +1 -0
- package/dist/tools/consolidated/checkpoint-tool.d.ts +66 -0
- package/dist/tools/consolidated/checkpoint-tool.d.ts.map +1 -0
- package/dist/tools/consolidated/checkpoint-tool.js +111 -0
- package/dist/tools/consolidated/checkpoint-tool.js.map +1 -0
- package/dist/tools/consolidated/validar.d.ts +63 -0
- package/dist/tools/consolidated/validar.d.ts.map +1 -0
- package/dist/tools/consolidated/validar.js +104 -0
- package/dist/tools/consolidated/validar.js.map +1 -0
- package/dist/tools/contexto.d.ts.map +1 -1
- package/dist/tools/contexto.js +18 -0
- package/dist/tools/contexto.js.map +1 -1
- package/dist/tools/discovery.d.ts +10 -10
- package/dist/tools/discovery.d.ts.map +1 -1
- package/dist/tools/discovery.js +82 -56
- package/dist/tools/discovery.js.map +1 -1
- package/dist/tools/iniciar-projeto.d.ts +48 -0
- package/dist/tools/iniciar-projeto.d.ts.map +1 -1
- package/dist/tools/iniciar-projeto.js +234 -45
- package/dist/tools/iniciar-projeto.js.map +1 -1
- package/dist/tools/maestro-tool.d.ts +51 -0
- package/dist/tools/maestro-tool.d.ts.map +1 -0
- package/dist/tools/maestro-tool.js +224 -0
- package/dist/tools/maestro-tool.js.map +1 -0
- package/dist/tools/prd-writer.d.ts +1 -1
- package/dist/tools/prd-writer.d.ts.map +1 -1
- package/dist/tools/prd-writer.js +138 -2
- package/dist/tools/prd-writer.js.map +1 -1
- package/dist/tools/proximo.d.ts.map +1 -1
- package/dist/tools/proximo.js +22 -16
- package/dist/tools/proximo.js.map +1 -1
- package/dist/tools/salvar.d.ts.map +1 -1
- package/dist/tools/salvar.js +13 -0
- package/dist/tools/salvar.js.map +1 -1
- package/dist/tools/setup-inicial.d.ts.map +1 -1
- package/dist/tools/setup-inicial.js +12 -0
- package/dist/tools/setup-inicial.js.map +1 -1
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/status.js +6 -0
- package/dist/tools/status.js.map +1 -1
- package/dist/tools/validar-gate.d.ts.map +1 -1
- package/dist/tools/validar-gate.js +25 -0
- package/dist/tools/validar-gate.js.map +1 -1
- package/dist/types/index.d.ts +20 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/response.d.ts +49 -0
- package/dist/types/response.d.ts.map +1 -1
- package/dist/types/response.js.map +1 -1
- package/dist/utils/smart-defaults.d.ts +56 -0
- package/dist/utils/smart-defaults.d.ts.map +1 -0
- package/dist/utils/smart-defaults.js +113 -0
- package/dist/utils/smart-defaults.js.map +1 -0
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -5,46 +5,73 @@
|
|
|
5
5
|
* Uso: node dist/stdio.js [diretorio]
|
|
6
6
|
* Ou via npx após publicar no npm
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* v5: Skills como MCP Resources, MCP Prompts capability,
|
|
9
|
+
* tools consolidadas (8 públicas + legadas backward-compatible)
|
|
10
|
+
*
|
|
11
|
+
* NOTA: Usa router centralizado (router.ts) para roteamento de tools.
|
|
12
|
+
* Não duplicar switch/case aqui - todas as tools são registradas no router.
|
|
9
13
|
*/
|
|
10
14
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
11
15
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
-
import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
16
|
+
import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
13
17
|
import { listarEspecialistas, listarTemplates, listarGuias, lerEspecialista, lerTemplate, lerGuia, lerPrompt, setProjectDirectory, } from "./utils/files.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { classificar } from "./tools/classificar.js";
|
|
21
|
-
import { salvar } from "./tools/salvar.js";
|
|
22
|
-
import { injetar_conteudo } from "./tools/injetar-conteudo.js";
|
|
23
|
-
// 🆕 FASE 1: Knowledge Base
|
|
24
|
-
import { recordADR, recordADRSchema, recordPattern, recordPatternSchema, getContext, getContextSchema, searchKnowledge, searchKnowledgeSchema, } from "./tools/fase1/knowledge.tools.js";
|
|
25
|
-
// 🆕 FASE 1: Checkpoint
|
|
26
|
-
import { createCheckpoint, createCheckpointSchema, rollbackTotal, rollbackTotalSchema, rollbackPartial, rollbackPartialSchema, listCheckpoints, listCheckpointsSchema, } from "./tools/fase1/checkpoint.tools.js";
|
|
27
|
-
// 🆕 FASE 1: Validation
|
|
28
|
-
import { validateDependencies, validateDependenciesSchema, validateSecurity, validateSecuritySchema, checkCompliance, checkComplianceSchema, } from "./tools/fase1/validation.tools.js";
|
|
29
|
-
// 🆕 FASE 1: Risk, AutoFix, Discovery
|
|
30
|
-
import { evaluateRisk, evaluateRiskSchema, autoFix, autoFixSchema, discoverCodebase, discoverCodebaseSchema, } from "./tools/fase1/misc.tools.js";
|
|
18
|
+
import { routeToolCall, getRegisteredTools, getToolCount } from "./router.js";
|
|
19
|
+
import { ContentResolverService } from "./services/content-resolver.service.js";
|
|
20
|
+
import { SkillLoaderService } from "./services/skill-loader.service.js";
|
|
21
|
+
import { createStateService } from "./services/state.service.js";
|
|
22
|
+
import { getSpecialistPersona } from "./services/specialist.service.js";
|
|
23
|
+
import { getFaseComStitch } from "./flows/types.js";
|
|
31
24
|
// Criar servidor MCP
|
|
32
25
|
const server = new Server({
|
|
33
26
|
name: "mcp-maestro",
|
|
34
|
-
version: "
|
|
27
|
+
version: "5.0.0",
|
|
35
28
|
}, {
|
|
36
29
|
capabilities: {
|
|
37
30
|
resources: {},
|
|
38
31
|
tools: {},
|
|
32
|
+
prompts: {},
|
|
39
33
|
},
|
|
40
34
|
});
|
|
41
|
-
// ==================== RESOURCES ====================
|
|
35
|
+
// ==================== RESOURCES (v5: Skills expandidas) ====================
|
|
42
36
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
43
37
|
const especialistas = await listarEspecialistas();
|
|
44
38
|
const templates = await listarTemplates();
|
|
45
39
|
const guias = await listarGuias();
|
|
40
|
+
// v5: Listar skills como resources estruturados
|
|
41
|
+
const contentResolver = new ContentResolverService(projectsDir);
|
|
42
|
+
const skills = await contentResolver.listAvailableSkills();
|
|
43
|
+
const skillResources = [];
|
|
44
|
+
for (const skillName of skills) {
|
|
45
|
+
// SKILL.md principal
|
|
46
|
+
skillResources.push({
|
|
47
|
+
uri: `maestro://skills/${skillName}/SKILL.md`,
|
|
48
|
+
name: `Skill: ${skillName}`,
|
|
49
|
+
mimeType: "text/markdown",
|
|
50
|
+
});
|
|
51
|
+
// Templates da skill
|
|
52
|
+
const skillTemplates = await contentResolver.listSkillResources(skillName, "templates");
|
|
53
|
+
for (const t of skillTemplates) {
|
|
54
|
+
skillResources.push({
|
|
55
|
+
uri: `maestro://skills/${skillName}/templates/${t}`,
|
|
56
|
+
name: `${skillName} Template: ${t}`,
|
|
57
|
+
mimeType: "text/markdown",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Checklists da skill
|
|
61
|
+
const checklists = await contentResolver.listSkillResources(skillName, "checklists");
|
|
62
|
+
for (const c of checklists) {
|
|
63
|
+
skillResources.push({
|
|
64
|
+
uri: `maestro://skills/${skillName}/checklists/${c}`,
|
|
65
|
+
name: `${skillName} Checklist: ${c}`,
|
|
66
|
+
mimeType: "text/markdown",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
46
70
|
return {
|
|
47
71
|
resources: [
|
|
72
|
+
// v5: Skills estruturadas (prioridade)
|
|
73
|
+
...skillResources,
|
|
74
|
+
// Legacy: especialistas, templates, guias
|
|
48
75
|
...especialistas.map((e) => ({
|
|
49
76
|
uri: `maestro://especialista/${encodeURIComponent(e)}`,
|
|
50
77
|
name: `Especialista: ${e}`,
|
|
@@ -70,6 +97,30 @@ server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
|
70
97
|
});
|
|
71
98
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
72
99
|
const { uri } = request.params;
|
|
100
|
+
// v5: Skills como resources
|
|
101
|
+
if (uri.startsWith("maestro://skills/")) {
|
|
102
|
+
const path = uri.replace("maestro://skills/", "");
|
|
103
|
+
const parts = path.split("/");
|
|
104
|
+
const skillName = parts[0];
|
|
105
|
+
const contentResolver = new ContentResolverService(projectsDir);
|
|
106
|
+
if (parts.length === 2 && parts[1] === "SKILL.md") {
|
|
107
|
+
// maestro://skills/{skill}/SKILL.md
|
|
108
|
+
const content = await contentResolver.readSkillFile(skillName, "SKILL.md");
|
|
109
|
+
if (!content)
|
|
110
|
+
throw new Error(`SKILL.md não encontrado: ${skillName}`);
|
|
111
|
+
return { contents: [{ uri, mimeType: "text/markdown", text: content }] };
|
|
112
|
+
}
|
|
113
|
+
if (parts.length === 3) {
|
|
114
|
+
// maestro://skills/{skill}/{tipo}/{arquivo}
|
|
115
|
+
const tipo = parts[1];
|
|
116
|
+
const arquivo = parts[2];
|
|
117
|
+
const content = await contentResolver.readSkillResource(skillName, tipo, arquivo);
|
|
118
|
+
if (!content)
|
|
119
|
+
throw new Error(`Resource não encontrado: ${uri}`);
|
|
120
|
+
return { contents: [{ uri, mimeType: "text/markdown", text: content }] };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Legacy: especialistas
|
|
73
124
|
if (uri.startsWith("maestro://especialista/")) {
|
|
74
125
|
const nome = decodeURIComponent(uri.replace("maestro://especialista/", ""));
|
|
75
126
|
const conteudo = await lerEspecialista(nome);
|
|
@@ -92,445 +143,286 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
92
143
|
return { contents: [{ uri, mimeType: "text/markdown", text: conteudo }] };
|
|
93
144
|
}
|
|
94
145
|
if (uri === "maestro://system-prompt") {
|
|
95
|
-
const conteudo = `# Maestro
|
|
146
|
+
const conteudo = `# Maestro v5 — Instruções para IA
|
|
96
147
|
|
|
97
|
-
Você está usando o Maestro, um
|
|
148
|
+
Você está usando o Maestro v5, um orquestrador de desenvolvimento assistido por IA.
|
|
98
149
|
|
|
99
|
-
## Modo
|
|
150
|
+
## Modo Híbrido (v5)
|
|
100
151
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
152
|
+
O Maestro v5 opera em modo híbrido:
|
|
153
|
+
- **Estado carregado automaticamente** de .maestro/estado.json (não precisa passar como parâmetro)
|
|
154
|
+
- **Skills injetadas ativamente** nas respostas das tools (não precisa ler manualmente)
|
|
155
|
+
- **Persistência automática** — o MCP salva estado e arquivos diretamente
|
|
156
|
+
- **Fallback stateless** — estado_json como parâmetro ainda aceito para compatibilidade
|
|
105
157
|
|
|
106
158
|
## Comportamentos Automáticos
|
|
107
159
|
|
|
108
160
|
Quando o usuário disser "próximo", "avançar", "terminei" ou "pronto":
|
|
109
|
-
1.
|
|
110
|
-
2.
|
|
111
|
-
3.
|
|
112
|
-
4.
|
|
161
|
+
1. Chame \`avancar(diretorio: "<path>")\`
|
|
162
|
+
2. O Maestro detecta contexto automaticamente
|
|
163
|
+
3. O contexto do especialista já vem incluído na resposta
|
|
164
|
+
4. Siga as instruções do especialista e template retornados
|
|
113
165
|
|
|
114
|
-
## Tools Disponíveis (
|
|
166
|
+
## Tools Disponíveis (v5 Consolidadas)
|
|
115
167
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
168
|
+
| Tool | Descrição |
|
|
169
|
+
|------|-----------|
|
|
170
|
+
| \`maestro(diretorio)\` | Entry point inteligente — detecta contexto e guia |
|
|
171
|
+
| \`avancar(diretorio, entregavel?)\` | Avança fase (onboarding ou desenvolvimento) |
|
|
172
|
+
| \`status(diretorio)\` | Status completo do projeto |
|
|
173
|
+
| \`validar(diretorio, tipo?)\` | Valida gate, entregável ou compliance |
|
|
174
|
+
| \`contexto(diretorio)\` | Contexto acumulado (ADRs, padrões) |
|
|
175
|
+
| \`salvar(diretorio, conteudo, tipo)\` | Salva rascunhos/anexos |
|
|
176
|
+
| \`checkpoint(diretorio, acao)\` | Gerencia checkpoints e rollbacks |
|
|
177
|
+
| \`analisar(diretorio, tipo?)\` | Análise de código (segurança, qualidade, etc.) |
|
|
178
|
+
|
|
179
|
+
> **Nota:** Tools legadas (proximo, validar_gate, etc.) ainda funcionam para backward compatibility.
|
|
124
180
|
`;
|
|
125
181
|
return { contents: [{ uri, mimeType: "text/markdown", text: conteudo }] };
|
|
126
182
|
}
|
|
127
183
|
throw new Error(`Resource não encontrado: ${uri}`);
|
|
128
184
|
});
|
|
129
|
-
// ====================
|
|
130
|
-
server.setRequestHandler(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
required: ["nome", "diretorio"],
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
name: "confirmar_projeto",
|
|
148
|
-
description: "Confirma criação do projeto com tipo e complexidade. Injeta conteúdo automaticamente.",
|
|
149
|
-
inputSchema: {
|
|
150
|
-
type: "object",
|
|
151
|
-
properties: {
|
|
152
|
-
nome: { type: "string", description: "Nome do projeto" },
|
|
153
|
-
descricao: { type: "string", description: "Descrição opcional" },
|
|
154
|
-
diretorio: { type: "string", description: "Diretório absoluto do projeto" },
|
|
155
|
-
tipo_artefato: { type: "string", enum: ["poc", "script", "internal", "product"], description: "Tipo de artefato" },
|
|
156
|
-
nivel_complexidade: { type: "string", enum: ["simples", "medio", "complexo"], description: "Nível de complexidade" },
|
|
157
|
-
ide: { type: "string", enum: ["windsurf", "cursor", "antigravity"], description: "IDE alvo para injection" },
|
|
158
|
-
},
|
|
159
|
-
required: ["nome", "diretorio", "tipo_artefato", "nivel_complexidade", "ide"],
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
name: "carregar_projeto",
|
|
164
|
-
description: "Carrega projeto existente (stateless). Requer estado_json.",
|
|
165
|
-
inputSchema: {
|
|
166
|
-
type: "object",
|
|
167
|
-
properties: {
|
|
168
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
169
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
170
|
-
},
|
|
171
|
-
required: ["estado_json", "diretorio"],
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
name: "proximo",
|
|
176
|
-
description: "Salva entregável e avança fase (stateless). Requer estado_json.",
|
|
177
|
-
inputSchema: {
|
|
178
|
-
type: "object",
|
|
179
|
-
properties: {
|
|
180
|
-
entregavel: { type: "string", description: "Conteúdo do entregável" },
|
|
181
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
182
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
183
|
-
nome_arquivo: { type: "string", description: "Nome do arquivo" },
|
|
184
|
-
},
|
|
185
|
-
required: ["entregavel", "estado_json", "diretorio"],
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
name: "status",
|
|
190
|
-
description: "Retorna status do projeto (stateless). Requer estado_json.",
|
|
191
|
-
inputSchema: {
|
|
192
|
-
type: "object",
|
|
193
|
-
properties: {
|
|
194
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
195
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
196
|
-
},
|
|
197
|
-
required: ["estado_json", "diretorio"],
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
name: "validar_gate",
|
|
202
|
-
description: "Valida checklist de saída (stateless). Requer estado_json.",
|
|
203
|
-
inputSchema: {
|
|
204
|
-
type: "object",
|
|
205
|
-
properties: {
|
|
206
|
-
fase: { type: "number", description: "Número da fase" },
|
|
207
|
-
entregavel: { type: "string", description: "Conteúdo para validar" },
|
|
208
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
209
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
210
|
-
},
|
|
211
|
-
required: ["estado_json", "diretorio"],
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: "contexto",
|
|
216
|
-
description: "Retorna contexto do projeto (stateless). Requer estado_json.",
|
|
217
|
-
inputSchema: {
|
|
218
|
-
type: "object",
|
|
219
|
-
properties: {
|
|
220
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
221
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
222
|
-
},
|
|
223
|
-
required: ["estado_json", "diretorio"],
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
name: "classificar",
|
|
228
|
-
description: "Reclassifica complexidade (stateless). Requer estado_json.",
|
|
229
|
-
inputSchema: {
|
|
230
|
-
type: "object",
|
|
231
|
-
properties: {
|
|
232
|
-
prd: { type: "string", description: "Conteúdo do PRD" },
|
|
233
|
-
nivel: { type: "string", enum: ["simples", "medio", "complexo"] },
|
|
234
|
-
estado_json: { type: "string", description: "Conteúdo de .maestro/estado.json" },
|
|
235
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
236
|
-
},
|
|
237
|
-
required: ["estado_json", "diretorio"],
|
|
185
|
+
// ==================== PROMPTS (v5: System Prompt Automático) ====================
|
|
186
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
187
|
+
return {
|
|
188
|
+
prompts: [
|
|
189
|
+
{
|
|
190
|
+
name: "maestro-specialist",
|
|
191
|
+
description: "Persona + instruções do especialista da fase atual do projeto",
|
|
192
|
+
arguments: [
|
|
193
|
+
{
|
|
194
|
+
name: "diretorio",
|
|
195
|
+
description: "Diretório do projeto",
|
|
196
|
+
required: true,
|
|
197
|
+
},
|
|
198
|
+
],
|
|
238
199
|
},
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
diretorio: { type: "string", description: "Diretório do projeto" },
|
|
250
|
-
},
|
|
251
|
-
required: ["conteudo", "tipo", "estado_json", "diretorio"],
|
|
200
|
+
{
|
|
201
|
+
name: "maestro-context",
|
|
202
|
+
description: "Contexto completo do projeto para a sessão de trabalho",
|
|
203
|
+
arguments: [
|
|
204
|
+
{
|
|
205
|
+
name: "diretorio",
|
|
206
|
+
description: "Diretório do projeto",
|
|
207
|
+
required: true,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
252
210
|
},
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
force: { type: "boolean", description: "Sobrescrever se já existe (padrão: false)" },
|
|
264
|
-
},
|
|
265
|
-
required: ["diretorio"],
|
|
211
|
+
{
|
|
212
|
+
name: "maestro-template",
|
|
213
|
+
description: "Template do entregável esperado para a fase atual",
|
|
214
|
+
arguments: [
|
|
215
|
+
{
|
|
216
|
+
name: "diretorio",
|
|
217
|
+
description: "Diretório do projeto",
|
|
218
|
+
required: true,
|
|
219
|
+
},
|
|
220
|
+
],
|
|
266
221
|
},
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
description: "
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
description:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
name: "validate_dependencies",
|
|
313
|
-
description: "Valida dependências e detecta hallucinations",
|
|
314
|
-
inputSchema: validateDependenciesSchema,
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
name: "validate_security",
|
|
318
|
-
description: "Valida segurança contra OWASP Top 10",
|
|
319
|
-
inputSchema: validateSecuritySchema,
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
name: "check_compliance",
|
|
323
|
-
description: "Verifica compliance (LGPD, PCI-DSS, HIPAA)",
|
|
324
|
-
inputSchema: checkComplianceSchema,
|
|
325
|
-
},
|
|
326
|
-
// 🆕 FASE 1: RISK, AUTOFIX, DISCOVERY
|
|
327
|
-
{
|
|
328
|
-
name: "evaluate_risk",
|
|
329
|
-
description: "Avalia risco de uma operação",
|
|
330
|
-
inputSchema: evaluateRiskSchema,
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
name: "auto_fix",
|
|
334
|
-
description: "Tenta corrigir automaticamente erros de código",
|
|
335
|
-
inputSchema: autoFixSchema,
|
|
336
|
-
},
|
|
337
|
-
{
|
|
338
|
-
name: "discover_codebase",
|
|
339
|
-
description: "Analisa codebase e detecta arquitetura/stack",
|
|
340
|
-
inputSchema: discoverCodebaseSchema,
|
|
341
|
-
},
|
|
342
|
-
],
|
|
343
|
-
}));
|
|
344
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
345
|
-
const { name, arguments: args } = request.params;
|
|
346
|
-
const a = args;
|
|
347
|
-
const typedArgs = a || {};
|
|
222
|
+
],
|
|
223
|
+
};
|
|
224
|
+
});
|
|
225
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
226
|
+
const { name, arguments: promptArgs } = request.params;
|
|
227
|
+
const diretorio = promptArgs?.diretorio || projectsDir;
|
|
228
|
+
if (name === "maestro-specialist") {
|
|
229
|
+
return await buildSpecialistPrompt(diretorio);
|
|
230
|
+
}
|
|
231
|
+
if (name === "maestro-context") {
|
|
232
|
+
return await buildContextPrompt(diretorio);
|
|
233
|
+
}
|
|
234
|
+
if (name === "maestro-template") {
|
|
235
|
+
return await buildTemplatePrompt(diretorio);
|
|
236
|
+
}
|
|
237
|
+
throw new Error(`Prompt não encontrado: ${name}`);
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* Constrói prompt dinâmico do especialista da fase atual.
|
|
241
|
+
*/
|
|
242
|
+
async function buildSpecialistPrompt(diretorio) {
|
|
243
|
+
const stateService = createStateService(diretorio);
|
|
244
|
+
const estado = await stateService.load();
|
|
245
|
+
if (!estado) {
|
|
246
|
+
return {
|
|
247
|
+
description: "Nenhum projeto encontrado",
|
|
248
|
+
messages: [{
|
|
249
|
+
role: "user",
|
|
250
|
+
content: { type: "text", text: "Nenhum projeto ativo neste diretório. Use `maestro(diretorio)` para começar." },
|
|
251
|
+
}],
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
const faseInfo = getFaseComStitch(estado.nivel, estado.fase_atual, estado.usar_stitch);
|
|
255
|
+
if (!faseInfo) {
|
|
256
|
+
return {
|
|
257
|
+
description: `Projeto: ${estado.nome}`,
|
|
258
|
+
messages: [{
|
|
259
|
+
role: "user",
|
|
260
|
+
content: { type: "text", text: `Projeto ${estado.nome} — fase ${estado.fase_atual} não encontrada no fluxo.` },
|
|
261
|
+
}],
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
const mode = (estado.config?.mode || "balanced");
|
|
265
|
+
const contentResolver = new ContentResolverService(diretorio);
|
|
266
|
+
const skillLoader = new SkillLoaderService(contentResolver);
|
|
348
267
|
try {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
descricao: typedArgs.descricao,
|
|
362
|
-
diretorio: typedArgs.diretorio,
|
|
363
|
-
tipo_artefato: typedArgs.tipo_artefato,
|
|
364
|
-
nivel_complexidade: typedArgs.nivel_complexidade,
|
|
365
|
-
ide: typedArgs.ide,
|
|
366
|
-
modo: typedArgs.modo,
|
|
367
|
-
});
|
|
368
|
-
case "carregar_projeto":
|
|
369
|
-
return await carregarProjeto({
|
|
370
|
-
estado_json: typedArgs.estado_json,
|
|
371
|
-
diretorio: typedArgs.diretorio,
|
|
372
|
-
});
|
|
373
|
-
case "proximo":
|
|
374
|
-
return await proximo({
|
|
375
|
-
entregavel: typedArgs.entregavel,
|
|
376
|
-
estado_json: typedArgs.estado_json,
|
|
377
|
-
diretorio: typedArgs.diretorio,
|
|
378
|
-
nome_arquivo: typedArgs.nome_arquivo,
|
|
379
|
-
});
|
|
380
|
-
case "status":
|
|
381
|
-
return await status({
|
|
382
|
-
estado_json: typedArgs.estado_json,
|
|
383
|
-
diretorio: typedArgs.diretorio,
|
|
384
|
-
});
|
|
385
|
-
case "validar_gate":
|
|
386
|
-
return await validarGate({
|
|
387
|
-
fase: typedArgs.fase,
|
|
388
|
-
entregavel: typedArgs.entregavel,
|
|
389
|
-
estado_json: typedArgs.estado_json,
|
|
390
|
-
diretorio: typedArgs.diretorio,
|
|
391
|
-
});
|
|
392
|
-
case "contexto":
|
|
393
|
-
return await contexto({
|
|
394
|
-
estado_json: typedArgs.estado_json,
|
|
395
|
-
diretorio: typedArgs.diretorio,
|
|
396
|
-
});
|
|
397
|
-
case "classificar":
|
|
398
|
-
return await classificar({
|
|
399
|
-
prd: typedArgs.prd,
|
|
400
|
-
nivel: typedArgs.nivel,
|
|
401
|
-
estado_json: typedArgs.estado_json,
|
|
402
|
-
diretorio: typedArgs.diretorio,
|
|
403
|
-
});
|
|
404
|
-
case "salvar":
|
|
405
|
-
return await salvar({
|
|
406
|
-
conteudo: typedArgs.conteudo,
|
|
407
|
-
tipo: typedArgs.tipo,
|
|
408
|
-
estado_json: typedArgs.estado_json,
|
|
409
|
-
diretorio: typedArgs.diretorio,
|
|
410
|
-
nome_arquivo: typedArgs.nome_arquivo,
|
|
411
|
-
});
|
|
412
|
-
case "injetar_conteudo":
|
|
413
|
-
return await injetar_conteudo({
|
|
414
|
-
diretorio: typedArgs.diretorio,
|
|
415
|
-
source: typedArgs.source,
|
|
416
|
-
custom_path: typedArgs.custom_path,
|
|
417
|
-
force: typedArgs.force,
|
|
418
|
-
});
|
|
419
|
-
// 🆕 FASE 1: KNOWLEDGE BASE
|
|
420
|
-
case "record_adr":
|
|
421
|
-
return await recordADR({
|
|
422
|
-
decision: typedArgs.decision,
|
|
423
|
-
context: typedArgs.context,
|
|
424
|
-
alternatives: typedArgs.alternatives,
|
|
425
|
-
consequences: typedArgs.consequences,
|
|
426
|
-
risks: typedArgs.risks,
|
|
427
|
-
estado_json: typedArgs.estado_json,
|
|
428
|
-
diretorio: typedArgs.diretorio,
|
|
429
|
-
});
|
|
430
|
-
case "record_pattern":
|
|
431
|
-
return await recordPattern({
|
|
432
|
-
name: typedArgs.name,
|
|
433
|
-
context: typedArgs.context,
|
|
434
|
-
problem: typedArgs.problem,
|
|
435
|
-
solution: typedArgs.solution,
|
|
436
|
-
examples: typedArgs.examples,
|
|
437
|
-
relatedPatterns: typedArgs.relatedPatterns,
|
|
438
|
-
estado_json: typedArgs.estado_json,
|
|
439
|
-
diretorio: typedArgs.diretorio,
|
|
440
|
-
});
|
|
441
|
-
case "get_context":
|
|
442
|
-
return await getContext({
|
|
443
|
-
fase: typedArgs.fase,
|
|
444
|
-
estado_json: typedArgs.estado_json,
|
|
445
|
-
diretorio: typedArgs.diretorio,
|
|
446
|
-
});
|
|
447
|
-
case "search_knowledge":
|
|
448
|
-
return await searchKnowledge({
|
|
449
|
-
query: typedArgs.query,
|
|
450
|
-
estado_json: typedArgs.estado_json,
|
|
451
|
-
diretorio: typedArgs.diretorio,
|
|
452
|
-
});
|
|
453
|
-
// 🆕 FASE 1: CHECKPOINT
|
|
454
|
-
case "create_checkpoint":
|
|
455
|
-
return await createCheckpoint({
|
|
456
|
-
reason: typedArgs.reason,
|
|
457
|
-
auto: typedArgs.auto,
|
|
458
|
-
estado_json: typedArgs.estado_json,
|
|
459
|
-
diretorio: typedArgs.diretorio,
|
|
460
|
-
});
|
|
461
|
-
case "rollback_total":
|
|
462
|
-
return await rollbackTotal({
|
|
463
|
-
checkpointId: typedArgs.checkpointId,
|
|
464
|
-
estado_json: typedArgs.estado_json,
|
|
465
|
-
diretorio: typedArgs.diretorio,
|
|
466
|
-
});
|
|
467
|
-
case "rollback_partial":
|
|
468
|
-
return await rollbackPartial({
|
|
469
|
-
checkpointId: typedArgs.checkpointId,
|
|
470
|
-
modules: typedArgs.modules,
|
|
471
|
-
estado_json: typedArgs.estado_json,
|
|
472
|
-
diretorio: typedArgs.diretorio,
|
|
473
|
-
});
|
|
474
|
-
case "list_checkpoints":
|
|
475
|
-
return await listCheckpoints({
|
|
476
|
-
estado_json: typedArgs.estado_json,
|
|
477
|
-
diretorio: typedArgs.diretorio,
|
|
478
|
-
});
|
|
479
|
-
// 🆕 FASE 1: VALIDATION
|
|
480
|
-
case "validate_dependencies":
|
|
481
|
-
return await validateDependencies({
|
|
482
|
-
code: typedArgs.code,
|
|
483
|
-
language: typedArgs.language,
|
|
484
|
-
estado_json: typedArgs.estado_json,
|
|
485
|
-
diretorio: typedArgs.diretorio,
|
|
486
|
-
});
|
|
487
|
-
case "validate_security":
|
|
488
|
-
return await validateSecurity({
|
|
489
|
-
code: typedArgs.code,
|
|
490
|
-
language: typedArgs.language,
|
|
491
|
-
estado_json: typedArgs.estado_json,
|
|
492
|
-
diretorio: typedArgs.diretorio,
|
|
493
|
-
});
|
|
494
|
-
case "check_compliance":
|
|
495
|
-
return await checkCompliance({
|
|
496
|
-
code: typedArgs.code,
|
|
497
|
-
standard: typedArgs.standard,
|
|
498
|
-
estado_json: typedArgs.estado_json,
|
|
499
|
-
diretorio: typedArgs.diretorio,
|
|
500
|
-
});
|
|
501
|
-
// 🆕 FASE 1: RISK, AUTOFIX, DISCOVERY
|
|
502
|
-
case "evaluate_risk":
|
|
503
|
-
return await evaluateRisk({
|
|
504
|
-
operation: typedArgs.operation,
|
|
505
|
-
context: typedArgs.context,
|
|
506
|
-
estado_json: typedArgs.estado_json,
|
|
507
|
-
diretorio: typedArgs.diretorio,
|
|
508
|
-
});
|
|
509
|
-
case "auto_fix":
|
|
510
|
-
return await autoFix({
|
|
511
|
-
code: typedArgs.code,
|
|
512
|
-
error: typedArgs.error,
|
|
513
|
-
estado_json: typedArgs.estado_json,
|
|
514
|
-
diretorio: typedArgs.diretorio,
|
|
515
|
-
});
|
|
516
|
-
case "discover_codebase":
|
|
517
|
-
return await discoverCodebase({
|
|
518
|
-
estado_json: typedArgs.estado_json,
|
|
519
|
-
diretorio: typedArgs.diretorio,
|
|
520
|
-
});
|
|
521
|
-
default:
|
|
522
|
-
return {
|
|
523
|
-
content: [{ type: "text", text: `Tool não encontrada: ${name}` }],
|
|
524
|
-
isError: true,
|
|
525
|
-
};
|
|
268
|
+
const contextPkg = await skillLoader.loadForPhase(faseInfo.nome, mode);
|
|
269
|
+
if (contextPkg) {
|
|
270
|
+
return {
|
|
271
|
+
description: `Especialista: ${contextPkg.specialist?.name || faseInfo.nome} — Fase ${estado.fase_atual}/${estado.total_fases}`,
|
|
272
|
+
messages: [{
|
|
273
|
+
role: "user",
|
|
274
|
+
content: {
|
|
275
|
+
type: "text",
|
|
276
|
+
text: `# Especialista da Fase: ${faseInfo.nome}\n\n${skillLoader.formatAsMarkdown(contextPkg)}`,
|
|
277
|
+
},
|
|
278
|
+
}],
|
|
279
|
+
};
|
|
526
280
|
}
|
|
527
281
|
}
|
|
528
282
|
catch (error) {
|
|
283
|
+
console.warn("[Prompt] Falha ao carregar skill:", error);
|
|
284
|
+
}
|
|
285
|
+
// Fallback: persona básica
|
|
286
|
+
const specialist = getSpecialistPersona(faseInfo.nome);
|
|
287
|
+
return {
|
|
288
|
+
description: `Especialista: ${specialist?.name || faseInfo.nome}`,
|
|
289
|
+
messages: [{
|
|
290
|
+
role: "user",
|
|
291
|
+
content: {
|
|
292
|
+
type: "text",
|
|
293
|
+
text: specialist
|
|
294
|
+
? `# ${specialist.name}\n\n**Tom:** ${specialist.tone}\n**Expertise:** ${specialist.expertise.join(", ")}\n**Instruções:** ${specialist.instructions}`
|
|
295
|
+
: `Fase ${estado.fase_atual}: ${faseInfo.nome}`,
|
|
296
|
+
},
|
|
297
|
+
}],
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Constrói prompt de contexto completo do projeto.
|
|
302
|
+
*/
|
|
303
|
+
async function buildContextPrompt(diretorio) {
|
|
304
|
+
const stateService = createStateService(diretorio);
|
|
305
|
+
const estado = await stateService.load();
|
|
306
|
+
if (!estado) {
|
|
307
|
+
return {
|
|
308
|
+
description: "Nenhum projeto encontrado",
|
|
309
|
+
messages: [{
|
|
310
|
+
role: "user",
|
|
311
|
+
content: { type: "text", text: "Nenhum projeto ativo neste diretório." },
|
|
312
|
+
}],
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const faseInfo = getFaseComStitch(estado.nivel, estado.fase_atual, estado.usar_stitch);
|
|
316
|
+
const contextText = `# Contexto do Projeto: ${estado.nome}
|
|
317
|
+
|
|
318
|
+
## Estado
|
|
319
|
+
| Campo | Valor |
|
|
320
|
+
|-------|-------|
|
|
321
|
+
| **Nível** | ${estado.nivel.toUpperCase()} |
|
|
322
|
+
| **Fase Atual** | ${estado.fase_atual}/${estado.total_fases} — ${faseInfo?.nome || "N/A"} |
|
|
323
|
+
| **Gates Validados** | ${estado.gates_validados?.join(", ") || "nenhum"} |
|
|
324
|
+
|
|
325
|
+
## Entregáveis Salvos
|
|
326
|
+
${Object.entries(estado.entregaveis || {}).map(([k, v]) => `- **${k}:** ${v}`).join("\n") || "Nenhum ainda."}
|
|
327
|
+
|
|
328
|
+
## Próximo Passo
|
|
329
|
+
Trabalhe com o especialista **${faseInfo?.especialista || "N/A"}** para gerar: **${faseInfo?.entregavel_esperado || "N/A"}**
|
|
330
|
+
`;
|
|
331
|
+
return {
|
|
332
|
+
description: `Projeto: ${estado.nome} — Fase ${estado.fase_atual}/${estado.total_fases}`,
|
|
333
|
+
messages: [{
|
|
334
|
+
role: "user",
|
|
335
|
+
content: { type: "text", text: contextText },
|
|
336
|
+
}],
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Constrói prompt do template da fase atual.
|
|
341
|
+
*/
|
|
342
|
+
async function buildTemplatePrompt(diretorio) {
|
|
343
|
+
const stateService = createStateService(diretorio);
|
|
344
|
+
const estado = await stateService.load();
|
|
345
|
+
if (!estado) {
|
|
346
|
+
return {
|
|
347
|
+
description: "Nenhum projeto encontrado",
|
|
348
|
+
messages: [{
|
|
349
|
+
role: "user",
|
|
350
|
+
content: { type: "text", text: "Nenhum projeto ativo neste diretório." },
|
|
351
|
+
}],
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
const faseInfo = getFaseComStitch(estado.nivel, estado.fase_atual, estado.usar_stitch);
|
|
355
|
+
if (!faseInfo) {
|
|
529
356
|
return {
|
|
530
|
-
|
|
531
|
-
|
|
357
|
+
description: `Projeto: ${estado.nome}`,
|
|
358
|
+
messages: [{
|
|
359
|
+
role: "user",
|
|
360
|
+
content: { type: "text", text: `Projeto ${estado.nome} — fase ${estado.fase_atual} não encontrada.` },
|
|
361
|
+
}],
|
|
532
362
|
};
|
|
533
363
|
}
|
|
364
|
+
const contentResolver = new ContentResolverService(diretorio);
|
|
365
|
+
const skillLoader = new SkillLoaderService(contentResolver);
|
|
366
|
+
try {
|
|
367
|
+
const templateContent = await skillLoader.loadTemplate(faseInfo.nome);
|
|
368
|
+
if (templateContent) {
|
|
369
|
+
return {
|
|
370
|
+
description: `Template: ${faseInfo.entregavel_esperado || faseInfo.nome}`,
|
|
371
|
+
messages: [{
|
|
372
|
+
role: "user",
|
|
373
|
+
content: {
|
|
374
|
+
type: "text",
|
|
375
|
+
text: `# Template do Entregável: ${faseInfo.entregavel_esperado || faseInfo.nome}
|
|
376
|
+
|
|
377
|
+
## Fase ${estado.fase_atual}/${estado.total_fases}: ${faseInfo.nome}
|
|
378
|
+
|
|
379
|
+
Use este template como base para gerar o entregável:
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
${templateContent}
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
> 💡 Dica: Preencha todas as seções marcadas com [...] ou indicadores de conteúdo.`,
|
|
388
|
+
},
|
|
389
|
+
}],
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
console.warn("[Prompt] Falha ao carregar template:", error);
|
|
395
|
+
}
|
|
396
|
+
// Fallback: estrutura básica
|
|
397
|
+
return {
|
|
398
|
+
description: `Template: ${faseInfo.entregavel_esperado || faseInfo.nome}`,
|
|
399
|
+
messages: [{
|
|
400
|
+
role: "user",
|
|
401
|
+
content: {
|
|
402
|
+
type: "text",
|
|
403
|
+
text: `# Template do Entregável: ${faseInfo.entregavel_esperado || faseInfo.nome}
|
|
404
|
+
|
|
405
|
+
## Fase ${estado.fase_atual}/${estado.total_fases}: ${faseInfo.nome}
|
|
406
|
+
|
|
407
|
+
### Estrutura Esperada
|
|
408
|
+
|
|
409
|
+
${faseInfo.gate_checklist.map((item, i) => `${i + 1}. ${item}`).join("\n")}
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
> ℹ️ Template específico não disponível. Use a lista acima como guia.`,
|
|
414
|
+
},
|
|
415
|
+
}],
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
// ==================== TOOLS (via Router Centralizado) ====================
|
|
419
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
420
|
+
tools: getRegisteredTools(),
|
|
421
|
+
}));
|
|
422
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
423
|
+
const { name, arguments: args } = request.params;
|
|
424
|
+
const rawArgs = args || {};
|
|
425
|
+
return await routeToolCall(name, rawArgs);
|
|
534
426
|
});
|
|
535
427
|
// ==================== START ====================
|
|
536
428
|
// Obter diretório dos argumentos ou usar cwd
|
|
@@ -540,7 +432,7 @@ setProjectDirectory(projectsDir);
|
|
|
540
432
|
async function main() {
|
|
541
433
|
const transport = new StdioServerTransport();
|
|
542
434
|
await server.connect(transport);
|
|
543
|
-
console.error(`MCP Maestro (stdio) iniciado
|
|
435
|
+
console.error(`MCP Maestro v5 (stdio) iniciado — ${getToolCount()} tools públicas`);
|
|
544
436
|
console.error(`Diretório de projetos: ${projectsDir}`);
|
|
545
437
|
}
|
|
546
438
|
main().catch(console.error);
|