refine-mcp 0.1.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/detection/compressor.d.ts +26 -0
- package/dist/detection/compressor.js +446 -0
- package/dist/detection/concern-map.d.ts +16 -0
- package/dist/detection/concern-map.js +236 -0
- package/dist/detection/context-extractor.d.ts +39 -0
- package/dist/detection/context-extractor.js +390 -0
- package/dist/detection/file-tree.d.ts +33 -0
- package/dist/detection/file-tree.js +174 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.js +125 -0
- package/dist/resources/identity.d.ts +6 -0
- package/dist/resources/identity.js +30 -0
- package/dist/resources/index.d.ts +6 -0
- package/dist/resources/index.js +14 -0
- package/dist/resources/prd.d.ts +6 -0
- package/dist/resources/prd.js +30 -0
- package/dist/resources/roadmap.d.ts +6 -0
- package/dist/resources/roadmap.js +30 -0
- package/dist/resources/tokens.d.ts +6 -0
- package/dist/resources/tokens.js +30 -0
- package/dist/setup.d.ts +11 -0
- package/dist/setup.js +429 -0
- package/dist/tools/checkin.d.ts +6 -0
- package/dist/tools/checkin.js +72 -0
- package/dist/tools/complete.d.ts +6 -0
- package/dist/tools/complete.js +56 -0
- package/dist/tools/get-prompt.d.ts +7 -0
- package/dist/tools/get-prompt.js +68 -0
- package/dist/tools/get-skill.d.ts +6 -0
- package/dist/tools/get-skill.js +57 -0
- package/dist/tools/refine-run.d.ts +22 -0
- package/dist/tools/refine-run.js +150 -0
- package/dist/utils/api.d.ts +12 -0
- package/dist/utils/api.js +69 -0
- package/dist/utils/config.d.ts +9 -0
- package/dist/utils/config.js +24 -0
- package/package.json +33 -0
package/dist/setup.js
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Setup wizard: npx @refine.build/mcp setup
|
|
4
|
+
*
|
|
5
|
+
* 1. Pede token (ou abre browser)
|
|
6
|
+
* 2. Detecta IDE (Claude Code, Cursor, Windsurf)
|
|
7
|
+
* 3. Gera config pro IDE detectado
|
|
8
|
+
* 4. Copia CLAUDE.md pro projeto se nao existe
|
|
9
|
+
* 5. Confirma setup
|
|
10
|
+
*/
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { createInterface } from "node:readline";
|
|
15
|
+
function detectIDE() {
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
18
|
+
// Cursor: .cursor/ dir exists
|
|
19
|
+
if (existsSync(join(cwd, ".cursor"))) {
|
|
20
|
+
return { ide: "cursor", label: "Cursor" };
|
|
21
|
+
}
|
|
22
|
+
// Windsurf: check config path
|
|
23
|
+
if (existsSync(join(home, ".codeium", "windsurf"))) {
|
|
24
|
+
return { ide: "windsurf", label: "Windsurf" };
|
|
25
|
+
}
|
|
26
|
+
// Gemini CLI / Antigravity: .gemini/ dir or GEMINI.md
|
|
27
|
+
if (existsSync(join(cwd, ".gemini")) || existsSync(join(cwd, "GEMINI.md"))) {
|
|
28
|
+
return { ide: "gemini", label: "Gemini CLI / Antigravity" };
|
|
29
|
+
}
|
|
30
|
+
// Replit: replit.nix or .replit
|
|
31
|
+
if (existsSync(join(cwd, "replit.nix")) || existsSync(join(cwd, ".replit"))) {
|
|
32
|
+
return { ide: "replit", label: "Replit" };
|
|
33
|
+
}
|
|
34
|
+
// Claude Code: check if CLAUDE.md exists
|
|
35
|
+
if (existsSync(join(cwd, "CLAUDE.md"))) {
|
|
36
|
+
return { ide: "claude-code", label: "Claude Code" };
|
|
37
|
+
}
|
|
38
|
+
// Codex: AGENTS.md is sufficient (OpenAI Codex reads AGENTS.md natively)
|
|
39
|
+
// Detected last since AGENTS.md might have been created by us
|
|
40
|
+
return { ide: "unknown", label: "Desconhecido" };
|
|
41
|
+
}
|
|
42
|
+
// --- Geração de config ---
|
|
43
|
+
function generateClaudeCodeCommand(token) {
|
|
44
|
+
return `claude mcp add refine -- npx -y @refine.build/mcp --token ${token}`;
|
|
45
|
+
}
|
|
46
|
+
function generateCursorConfig(token) {
|
|
47
|
+
const config = {
|
|
48
|
+
mcpServers: {
|
|
49
|
+
refine: {
|
|
50
|
+
command: "npx",
|
|
51
|
+
args: ["-y", "@refine.build/mcp", "--token", token],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
return JSON.stringify(config, null, 2);
|
|
56
|
+
}
|
|
57
|
+
function generateWindsurfConfig(token) {
|
|
58
|
+
const config = {
|
|
59
|
+
mcpServers: {
|
|
60
|
+
refine: {
|
|
61
|
+
command: "npx",
|
|
62
|
+
args: ["-y", "@refine.build/mcp", "--token", token],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return JSON.stringify(config, null, 2);
|
|
67
|
+
}
|
|
68
|
+
function generateWindowsConfig(token) {
|
|
69
|
+
const config = {
|
|
70
|
+
mcpServers: {
|
|
71
|
+
refine: {
|
|
72
|
+
command: "cmd",
|
|
73
|
+
args: ["/c", "npx", "-y", "@refine.build/mcp", "--token", token],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
return JSON.stringify(config, null, 2);
|
|
78
|
+
}
|
|
79
|
+
// --- AGENTS.md (padrao universal) ---
|
|
80
|
+
const AGENTS_MD_CONTENT = `# AGENTS.md — refine.build Product Builder Pipeline
|
|
81
|
+
|
|
82
|
+
> Este arquivo e lido automaticamente por Claude Code, Cursor, Windsurf, Codex, Gemini CLI, Replit, Aider, Zed, Warp, RooCode e outros agentes compatíveis com o padrao AGENTS.md.
|
|
83
|
+
|
|
84
|
+
## Pipeline
|
|
85
|
+
|
|
86
|
+
Este projeto segue o pipeline de 13 skills do Product Builder (refine.build).
|
|
87
|
+
O MCP server @refine.build/mcp esta configurado e sincroniza o progresso automaticamente.
|
|
88
|
+
|
|
89
|
+
## Tools MCP disponiveis
|
|
90
|
+
|
|
91
|
+
- **refine_checkin** — Escaneia o projeto e detecta a etapa ativa. Chame no inicio de cada sessao e apos mudancas significativas.
|
|
92
|
+
- **refine_get_skill** — Retorna a skill ativa, fase e o que fazer.
|
|
93
|
+
- **refine_complete_skill** — Marca a skill atual como concluida e desbloqueia a proxima.
|
|
94
|
+
- **refine_get_prompt** — Retorna o system prompt completo da skill pra conduzir o trabalho.
|
|
95
|
+
|
|
96
|
+
## Regras
|
|
97
|
+
|
|
98
|
+
1. No inicio de cada sessao, chame refine_checkin para verificar a skill ativa.
|
|
99
|
+
2. Apos criar ou modificar arquivos significativos (paginas, componentes, features, configuracoes), chame refine_checkin novamente.
|
|
100
|
+
3. Quando o builder disser que terminou uma etapa, chame refine_complete_skill.
|
|
101
|
+
4. Antes de iniciar uma nova skill, chame refine_get_prompt para obter as instrucoes completas.
|
|
102
|
+
5. Sempre informe ao builder em qual skill ele esta e o que falta fazer.
|
|
103
|
+
|
|
104
|
+
## Roadmap-first: nunca implemente sem mapear
|
|
105
|
+
|
|
106
|
+
Quando o builder pedir para criar algo novo, corrigir um bug ou adicionar uma feature:
|
|
107
|
+
1. Abra docs/roadmap.md e verifique se ja existe uma task mapeada para isso.
|
|
108
|
+
2. Se ja existe, siga a task normalmente.
|
|
109
|
+
3. Se NAO existe, antes de qualquer codigo:
|
|
110
|
+
- Proponha a task ao builder com: titulo, complexidade (simples/media/complexa), arquivos envolvidos e notas.
|
|
111
|
+
- Espere o builder aprovar.
|
|
112
|
+
- Insira a task no roadmap.md na fase correta, com o proximo TASK number disponivel.
|
|
113
|
+
- So entao implemente.
|
|
114
|
+
4. Ao concluir, marque [x] na task do roadmap.md. O checkin sincroniza o progresso automaticamente.
|
|
115
|
+
`;
|
|
116
|
+
// --- Regras do pipeline (IDE-specific, fallback) ---
|
|
117
|
+
const CLAUDE_MD_RULES = `## Refine.build — Product Builder Pipeline
|
|
118
|
+
Este projeto segue o pipeline de 13 skills do Product Builder.
|
|
119
|
+
Use os tools do MCP refine para manter o progresso sincronizado.
|
|
120
|
+
|
|
121
|
+
### Regras:
|
|
122
|
+
1. No inicio de cada sessao, chame refine_checkin para verificar a skill ativa.
|
|
123
|
+
2. Apos criar ou modificar arquivos significativos (paginas, componentes, features, configuracoes), chame refine_checkin novamente.
|
|
124
|
+
3. Quando o builder disser que terminou uma etapa, chame refine_complete_skill.
|
|
125
|
+
4. Antes de iniciar uma nova skill, chame refine_get_prompt para obter as instrucoes completas.
|
|
126
|
+
5. Sempre informe ao builder em qual skill ele esta e o que falta fazer.
|
|
127
|
+
|
|
128
|
+
### Roadmap-first: nunca implemente sem mapear
|
|
129
|
+
Quando o builder pedir para criar algo novo, corrigir um bug ou adicionar uma feature:
|
|
130
|
+
1. Abra docs/roadmap.md e verifique se ja existe uma task mapeada para isso.
|
|
131
|
+
2. Se ja existe, siga a task normalmente.
|
|
132
|
+
3. Se NAO existe, antes de qualquer codigo:
|
|
133
|
+
- Proponha a task ao builder com: titulo, complexidade (simples/media/complexa), arquivos envolvidos e notas.
|
|
134
|
+
- Espere o builder aprovar.
|
|
135
|
+
- Insira a task no roadmap.md na fase correta, com o proximo TASK number disponivel.
|
|
136
|
+
- So entao implemente.
|
|
137
|
+
4. Ao concluir, marque [x] na task do roadmap.md. O checkin sincroniza o progresso automaticamente.
|
|
138
|
+
`;
|
|
139
|
+
const CURSOR_RULES = `You are working on a project that follows the Product Builder 19-skill pipeline.
|
|
140
|
+
The refine MCP server is connected. Use its tools:
|
|
141
|
+
- Call refine_checkin at session start and after significant file changes.
|
|
142
|
+
- Call refine_complete_skill when a phase is done.
|
|
143
|
+
- Call refine_get_prompt before starting a new skill.
|
|
144
|
+
- Always tell the builder which skill they're on and what's next.
|
|
145
|
+
|
|
146
|
+
ROADMAP-FIRST RULE:
|
|
147
|
+
When the builder asks to create, fix or add anything:
|
|
148
|
+
1. Check docs/roadmap.md for an existing task.
|
|
149
|
+
2. If none exists, propose a task (title, complexity, files, notes) and wait for approval.
|
|
150
|
+
3. Insert the task in roadmap.md before writing any code.
|
|
151
|
+
4. After completing, mark [x] in roadmap.md. The MCP checkin syncs progress automatically.
|
|
152
|
+
`;
|
|
153
|
+
// --- Lovable Knowledge text (TASK-088F) ---
|
|
154
|
+
function printLovableKnowledgeInstructions() {
|
|
155
|
+
const text = generateLovableKnowledgeText();
|
|
156
|
+
console.log("");
|
|
157
|
+
console.log(" Lovable nao le AGENTS.md, entao cole o texto abaixo em:");
|
|
158
|
+
console.log(" Settings > Knowledge (limite: 10.000 chars)");
|
|
159
|
+
console.log("");
|
|
160
|
+
console.log(" --- INICIO DO TEXTO ---");
|
|
161
|
+
console.log(text);
|
|
162
|
+
console.log(" --- FIM DO TEXTO ---");
|
|
163
|
+
console.log("");
|
|
164
|
+
// Tentar copiar pro clipboard
|
|
165
|
+
try {
|
|
166
|
+
if (process.platform === "darwin") {
|
|
167
|
+
execSync("pbcopy", { input: text });
|
|
168
|
+
console.log(" Texto copiado pro clipboard!");
|
|
169
|
+
}
|
|
170
|
+
else if (process.platform === "linux") {
|
|
171
|
+
execSync("xclip -selection clipboard", { input: text });
|
|
172
|
+
console.log(" Texto copiado pro clipboard!");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Clipboard nao disponivel, ok
|
|
177
|
+
}
|
|
178
|
+
console.log("");
|
|
179
|
+
}
|
|
180
|
+
function generateLovableKnowledgeText() {
|
|
181
|
+
// Versao compacta das regras, otimizada pro limite de 10k chars do Lovable
|
|
182
|
+
return `# refine.build — Product Builder Pipeline
|
|
183
|
+
|
|
184
|
+
Este projeto segue o pipeline de 13 skills do Product Builder (refine.build).
|
|
185
|
+
|
|
186
|
+
## Regras
|
|
187
|
+
|
|
188
|
+
1. Antes de criar algo, verifique docs/roadmap.md pra tasks existentes.
|
|
189
|
+
2. Se nao existe task, proponha: titulo, complexidade, arquivos, notas. Espere aprovacao.
|
|
190
|
+
3. Insira a task no roadmap.md antes de codar.
|
|
191
|
+
4. Ao concluir, marque [x] na task do roadmap.md.
|
|
192
|
+
|
|
193
|
+
## Skills do Pipeline (ordem)
|
|
194
|
+
|
|
195
|
+
1. Product Strategy — Coleta de ideia, validacao, hook cycle
|
|
196
|
+
2. Identity — Nome, personalidade, tom visual
|
|
197
|
+
3. Design System — Tokens, cores, tipografia, componentes
|
|
198
|
+
4. Page Builder — Construir telas seguindo specs do PRD
|
|
199
|
+
5. Feature Dev — Conectar backend, CRUD, funcionalidades
|
|
200
|
+
6. Quality Auditor — Testes, responsividade, schema sync
|
|
201
|
+
7. Ship — Deploy, seguranca, performance, pre-launch
|
|
202
|
+
|
|
203
|
+
## Convenções
|
|
204
|
+
|
|
205
|
+
- Imports: usar @/ alias pra src/
|
|
206
|
+
- Styling: apenas tokens semanticos do design system
|
|
207
|
+
- Componentes: shadcn/ui como base
|
|
208
|
+
- Backend: Convex (mutations/queries). Auth check em tudo
|
|
209
|
+
- Testes: Vitest. Testar logica, nao UI
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
// --- Readline helper ---
|
|
213
|
+
function ask(rl, question) {
|
|
214
|
+
return new Promise((resolve) => {
|
|
215
|
+
rl.question(question, (answer) => resolve(answer.trim()));
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
// --- Main ---
|
|
219
|
+
async function main() {
|
|
220
|
+
const cwd = process.cwd();
|
|
221
|
+
const isWindows = process.platform === "win32";
|
|
222
|
+
console.log("");
|
|
223
|
+
console.log(" refine.build — Setup MCP");
|
|
224
|
+
console.log(" ========================");
|
|
225
|
+
console.log("");
|
|
226
|
+
const rl = createInterface({
|
|
227
|
+
input: process.stdin,
|
|
228
|
+
output: process.stdout,
|
|
229
|
+
});
|
|
230
|
+
// 1. Token
|
|
231
|
+
let token = "";
|
|
232
|
+
const argIndex = process.argv.indexOf("--token");
|
|
233
|
+
if (argIndex !== -1 && process.argv[argIndex + 1]) {
|
|
234
|
+
token = process.argv[argIndex + 1];
|
|
235
|
+
console.log(` Token: ${token.slice(0, 8)}...`);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
console.log(" Gere seu token em: https://refine.build/account/mcp");
|
|
239
|
+
console.log("");
|
|
240
|
+
token = await ask(rl, " Cole seu token: ");
|
|
241
|
+
if (!token) {
|
|
242
|
+
console.log("\n Token obrigatorio. Abortando.");
|
|
243
|
+
rl.close();
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// 2. Detectar IDE
|
|
248
|
+
const detected = detectIDE();
|
|
249
|
+
console.log(`\n IDE detectado: ${detected.label}`);
|
|
250
|
+
let ide = detected.ide;
|
|
251
|
+
if (ide === "unknown") {
|
|
252
|
+
console.log(" Nao consegui detectar automaticamente.");
|
|
253
|
+
console.log(" 1) Claude Code");
|
|
254
|
+
console.log(" 2) Cursor");
|
|
255
|
+
console.log(" 3) Windsurf");
|
|
256
|
+
console.log(" 4) Codex (OpenAI)");
|
|
257
|
+
console.log(" 5) Gemini CLI / Antigravity");
|
|
258
|
+
console.log(" 6) Replit");
|
|
259
|
+
console.log(" 7) Lovable");
|
|
260
|
+
const choice = await ask(rl, "\n Qual IDE? (1-7): ");
|
|
261
|
+
const ideMap = {
|
|
262
|
+
"1": "claude-code",
|
|
263
|
+
"2": "cursor",
|
|
264
|
+
"3": "windsurf",
|
|
265
|
+
"4": "codex",
|
|
266
|
+
"5": "gemini",
|
|
267
|
+
"6": "replit",
|
|
268
|
+
"7": "lovable",
|
|
269
|
+
};
|
|
270
|
+
ide = ideMap[choice] ?? "unknown";
|
|
271
|
+
if (ide === "unknown") {
|
|
272
|
+
console.log("\n Opcao invalida. Abortando.");
|
|
273
|
+
rl.close();
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// 3. Gerar config
|
|
278
|
+
console.log("");
|
|
279
|
+
switch (ide) {
|
|
280
|
+
case "claude-code": {
|
|
281
|
+
const cmd = generateClaudeCodeCommand(token);
|
|
282
|
+
console.log(" Execute este comando no terminal:");
|
|
283
|
+
console.log("");
|
|
284
|
+
console.log(` ${cmd}`);
|
|
285
|
+
console.log("");
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case "cursor": {
|
|
289
|
+
const configPath = join(cwd, ".cursor", "mcp.json");
|
|
290
|
+
const config = generateCursorConfig(token);
|
|
291
|
+
const shouldWrite = await ask(rl, ` Criar ${configPath}? (s/n): `);
|
|
292
|
+
if (shouldWrite.toLowerCase() === "s") {
|
|
293
|
+
mkdirSync(join(cwd, ".cursor"), { recursive: true });
|
|
294
|
+
if (existsSync(configPath)) {
|
|
295
|
+
console.log(` Arquivo ja existe. Adicione manualmente:`);
|
|
296
|
+
console.log("");
|
|
297
|
+
console.log(config);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
writeFileSync(configPath, config, "utf-8");
|
|
301
|
+
console.log(` Criado: ${configPath}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
console.log("\n Adicione ao .cursor/mcp.json:");
|
|
306
|
+
console.log("");
|
|
307
|
+
console.log(config);
|
|
308
|
+
}
|
|
309
|
+
console.log("");
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
case "windsurf": {
|
|
313
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
314
|
+
const configPath = join(home, ".codeium", "windsurf", "mcp_config.json");
|
|
315
|
+
const config = isWindows ? generateWindowsConfig(token) : generateWindsurfConfig(token);
|
|
316
|
+
console.log(` Adicione ao ${configPath}:`);
|
|
317
|
+
console.log("");
|
|
318
|
+
console.log(config);
|
|
319
|
+
console.log("");
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case "codex": {
|
|
323
|
+
// Codex usa AGENTS.md (gerado no step 4) + nao suporta MCP nativo
|
|
324
|
+
console.log(" Codex le o AGENTS.md automaticamente (gerado no proximo passo).");
|
|
325
|
+
console.log(" MCP nao suportado nativamente pelo Codex — regras via AGENTS.md.");
|
|
326
|
+
console.log("");
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
case "gemini": {
|
|
330
|
+
console.log(" Gemini CLI le o AGENTS.md automaticamente.");
|
|
331
|
+
console.log("");
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
case "replit": {
|
|
335
|
+
console.log(" Replit suporta MCP nativo.");
|
|
336
|
+
console.log(" Va em: Integrations > MCP Servers > Add MCP server");
|
|
337
|
+
console.log(` Nome: refine`);
|
|
338
|
+
console.log(` URL: https://mcp.refine.build/sse?token=${token}`);
|
|
339
|
+
console.log("");
|
|
340
|
+
console.log(" Replit Agent tambem le o AGENTS.md (gerado no proximo passo).");
|
|
341
|
+
console.log("");
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
case "lovable": {
|
|
345
|
+
console.log(" Lovable suporta MCP nativo (planos pagos).");
|
|
346
|
+
console.log(" Va em: Settings > Connectors > Personal Connectors > New MCP server");
|
|
347
|
+
console.log(` Nome: refine`);
|
|
348
|
+
console.log(` URL: https://mcp.refine.build/sse?token=${token}`);
|
|
349
|
+
console.log(" Auth: Bearer token");
|
|
350
|
+
console.log("");
|
|
351
|
+
console.log(" Lovable NAO le AGENTS.md. Cole as regras em Project Knowledge:");
|
|
352
|
+
printLovableKnowledgeInstructions();
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// 4. Gerar AGENTS.md (padrao universal)
|
|
357
|
+
const agentsMdPath = join(cwd, "AGENTS.md");
|
|
358
|
+
let rulesCreated = false;
|
|
359
|
+
if (!existsSync(agentsMdPath)) {
|
|
360
|
+
writeFileSync(agentsMdPath, AGENTS_MD_CONTENT, "utf-8");
|
|
361
|
+
console.log(" Criado: AGENTS.md (padrao universal, lido por todos os agentes)");
|
|
362
|
+
rulesCreated = true;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
console.log(" AGENTS.md ja existe (nao sobrescrito).");
|
|
366
|
+
}
|
|
367
|
+
// 5. Copiar regras IDE-specific como complemento
|
|
368
|
+
const claudeMdPath = join(cwd, "CLAUDE.md");
|
|
369
|
+
const cursorRulesPath = join(cwd, ".cursorrules");
|
|
370
|
+
const windsurfRulesPath = join(cwd, ".windsurfrules");
|
|
371
|
+
if (!existsSync(claudeMdPath)) {
|
|
372
|
+
writeFileSync(claudeMdPath, CLAUDE_MD_RULES, "utf-8");
|
|
373
|
+
console.log(" Criado: CLAUDE.md");
|
|
374
|
+
rulesCreated = true;
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
console.log(" CLAUDE.md ja existe (nao sobrescrito).");
|
|
378
|
+
}
|
|
379
|
+
if (ide === "cursor" && !existsSync(cursorRulesPath)) {
|
|
380
|
+
writeFileSync(cursorRulesPath, CURSOR_RULES, "utf-8");
|
|
381
|
+
console.log(" Criado: .cursorrules");
|
|
382
|
+
rulesCreated = true;
|
|
383
|
+
}
|
|
384
|
+
if (ide === "windsurf" && !existsSync(windsurfRulesPath)) {
|
|
385
|
+
writeFileSync(windsurfRulesPath, CURSOR_RULES, "utf-8");
|
|
386
|
+
console.log(" Criado: .windsurfrules");
|
|
387
|
+
rulesCreated = true;
|
|
388
|
+
}
|
|
389
|
+
// Gemini: GEMINI.md + .agent/rules/refine.md
|
|
390
|
+
if (ide === "gemini") {
|
|
391
|
+
const geminiMdPath = join(cwd, "GEMINI.md");
|
|
392
|
+
if (!existsSync(geminiMdPath)) {
|
|
393
|
+
writeFileSync(geminiMdPath, AGENTS_MD_CONTENT, "utf-8");
|
|
394
|
+
console.log(" Criado: GEMINI.md");
|
|
395
|
+
rulesCreated = true;
|
|
396
|
+
}
|
|
397
|
+
const agentRulesDir = join(cwd, ".agent", "rules");
|
|
398
|
+
const agentRulePath = join(agentRulesDir, "refine.md");
|
|
399
|
+
if (!existsSync(agentRulePath)) {
|
|
400
|
+
mkdirSync(agentRulesDir, { recursive: true });
|
|
401
|
+
writeFileSync(agentRulePath, AGENTS_MD_CONTENT, "utf-8");
|
|
402
|
+
console.log(" Criado: .agent/rules/refine.md");
|
|
403
|
+
rulesCreated = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Replit: replit.md
|
|
407
|
+
if (ide === "replit") {
|
|
408
|
+
const replitMdPath = join(cwd, "replit.md");
|
|
409
|
+
if (!existsSync(replitMdPath)) {
|
|
410
|
+
writeFileSync(replitMdPath, AGENTS_MD_CONTENT, "utf-8");
|
|
411
|
+
console.log(" Criado: replit.md");
|
|
412
|
+
rulesCreated = true;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// 6. Confirmar
|
|
416
|
+
console.log("");
|
|
417
|
+
console.log(" ========================");
|
|
418
|
+
console.log(" MCP configurado!");
|
|
419
|
+
if (rulesCreated) {
|
|
420
|
+
console.log(" Regras do pipeline copiadas pro projeto.");
|
|
421
|
+
}
|
|
422
|
+
console.log(" A IA do seu IDE agora sincroniza com o refine.build.");
|
|
423
|
+
console.log("");
|
|
424
|
+
rl.close();
|
|
425
|
+
}
|
|
426
|
+
main().catch((error) => {
|
|
427
|
+
console.error("Erro no setup:", error);
|
|
428
|
+
process.exit(1);
|
|
429
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_checkin: escaneia file tree do builder e detecta skill ativa.
|
|
3
|
+
* Chama automaticamente no inicio de cada sessao.
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
export declare function registerCheckinTool(server: McpServer): void;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_checkin: escaneia file tree do builder e detecta skill ativa.
|
|
3
|
+
* Chama automaticamente no inicio de cada sessao.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { detectSkill, scanFileTree } from "../detection/file-tree.js";
|
|
7
|
+
import { apiPost } from "../utils/api.js";
|
|
8
|
+
export function registerCheckinTool(server) {
|
|
9
|
+
server.registerTool("refine_checkin", {
|
|
10
|
+
description: "Escaneia o projeto do builder e detecta a etapa ativa no fluxo guiado do refine.build. Chame no inicio de cada sessao.",
|
|
11
|
+
annotations: {
|
|
12
|
+
readOnlyHint: false,
|
|
13
|
+
destructiveHint: false,
|
|
14
|
+
idempotentHint: true,
|
|
15
|
+
openWorldHint: true,
|
|
16
|
+
},
|
|
17
|
+
inputSchema: z.object({
|
|
18
|
+
projectId: z.string().optional().describe("ID do projeto no refine.build (opcional)"),
|
|
19
|
+
}),
|
|
20
|
+
}, async ({ projectId }) => {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
// 1. Scan file tree
|
|
23
|
+
const summary = await scanFileTree(cwd);
|
|
24
|
+
// 2. Detect skill
|
|
25
|
+
const detectedSkill = detectSkill(summary);
|
|
26
|
+
// 3. POST pro backend
|
|
27
|
+
const response = await apiPost("/api/mcp/checkin", {
|
|
28
|
+
projectId,
|
|
29
|
+
fileTreeSummary: summary,
|
|
30
|
+
detectedSkill,
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok || !response.data) {
|
|
33
|
+
return {
|
|
34
|
+
content: [
|
|
35
|
+
{
|
|
36
|
+
type: "text",
|
|
37
|
+
text: `Erro no checkin: ${response.error ?? "Sem resposta do servidor"}`,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const d = response.data;
|
|
43
|
+
if (d.error) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: `${d.error}${d.hint ? `. ${d.hint}` : ""}`,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// 4. Formatar resposta pra IA do IDE
|
|
54
|
+
const lines = [
|
|
55
|
+
`Etapa ativa: ${d.skillName} (fase ${d.skillPhase})`,
|
|
56
|
+
`O que fazer: ${d.skillDescription}`,
|
|
57
|
+
d.nextSkill ? `Proxima etapa: ${d.nextSkill}` : "Ultima etapa do fluxo!",
|
|
58
|
+
`Progresso: ${d.progressPercent}% (${d.completedSkills}/${d.totalSkills} etapas)`,
|
|
59
|
+
`Projeto: ${d.projectId}`,
|
|
60
|
+
"",
|
|
61
|
+
`Deteccao local: ${detectedSkill} | Scan: ${summary.pages.length} paginas, ${summary.tests.length} testes, ${summary.mutations.length} mutations, ${summary.cssVarCount} CSS vars`,
|
|
62
|
+
];
|
|
63
|
+
// Adicionar progresso do roadmap.md se disponivel
|
|
64
|
+
if (summary.roadmapTasks) {
|
|
65
|
+
const rt = summary.roadmapTasks;
|
|
66
|
+
const pct = rt.total > 0 ? Math.round((rt.done / rt.total) * 100) : 0;
|
|
67
|
+
lines.push(`Roadmap: ${rt.done}/${rt.total} tasks (${pct}%)`);
|
|
68
|
+
}
|
|
69
|
+
const text = lines.join("\n");
|
|
70
|
+
return { content: [{ type: "text", text }] };
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_complete_skill: marca skill ativa como concluida e avanca pro proximo.
|
|
3
|
+
* Usar quando o builder diz "terminei" ou quando a IA detecta que a skill foi concluida.
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
export declare function registerCompleteSkillTool(server: McpServer): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_complete_skill: marca skill ativa como concluida e avanca pro proximo.
|
|
3
|
+
* Usar quando o builder diz "terminei" ou quando a IA detecta que a skill foi concluida.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { apiPost } from "../utils/api.js";
|
|
7
|
+
export function registerCompleteSkillTool(server) {
|
|
8
|
+
server.registerTool("refine_complete_skill", {
|
|
9
|
+
description: "Marca a etapa ativa como concluida e avanca pra proxima. Use quando o builder completar uma etapa no IDE.",
|
|
10
|
+
annotations: {
|
|
11
|
+
readOnlyHint: false,
|
|
12
|
+
destructiveHint: false,
|
|
13
|
+
idempotentHint: false,
|
|
14
|
+
openWorldHint: true,
|
|
15
|
+
},
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
skillId: z.string().describe("ID da skill a completar (ex: 'page-builder', 'onboarding')"),
|
|
18
|
+
projectId: z.string().optional().describe("ID do projeto (opcional, usa o mais recente)"),
|
|
19
|
+
evidence: z
|
|
20
|
+
.array(z.string())
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Lista de arquivos criados/modificados como evidencia (opcional)"),
|
|
23
|
+
}),
|
|
24
|
+
}, async ({ skillId, projectId, evidence }) => {
|
|
25
|
+
const body = { skillId };
|
|
26
|
+
if (projectId)
|
|
27
|
+
body.projectId = projectId;
|
|
28
|
+
if (evidence)
|
|
29
|
+
body.evidence = evidence;
|
|
30
|
+
const response = await apiPost("/api/mcp/complete-skill", body);
|
|
31
|
+
if (!response.ok || !response.data) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: `Erro ao completar skill: ${response.error ?? "Sem resposta do servidor"}`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const d = response.data;
|
|
42
|
+
if (d.error) {
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: `Erro: ${d.error}` }],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const lines = [
|
|
48
|
+
`Skill concluida: ${d.completedSkill}`,
|
|
49
|
+
d.nextSkill
|
|
50
|
+
? `Proxima skill: ${d.nextSkill}`
|
|
51
|
+
: "Pipeline completo! Todas as skills foram concluidas.",
|
|
52
|
+
`Progresso: ${d.progressPercent}%`,
|
|
53
|
+
];
|
|
54
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_get_prompt: retorna system prompt completo de uma skill.
|
|
3
|
+
* Tenta composicao (POST compose-skill com contexto local) primeiro,
|
|
4
|
+
* fallback pro GET skill-prompt se composicao falhar.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
export declare function registerGetPromptTool(server: McpServer): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_get_prompt: retorna system prompt completo de uma skill.
|
|
3
|
+
* Tenta composicao (POST compose-skill com contexto local) primeiro,
|
|
4
|
+
* fallback pro GET skill-prompt se composicao falhar.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { extractProjectContext } from "../detection/context-extractor.js";
|
|
8
|
+
import { apiGet, apiPost } from "../utils/api.js";
|
|
9
|
+
export function registerGetPromptTool(server) {
|
|
10
|
+
server.registerTool("refine_get_prompt", {
|
|
11
|
+
description: "Retorna o system prompt completo de uma etapa do fluxo. Use como instrucao pra conduzir a etapa no IDE do builder.",
|
|
12
|
+
annotations: {
|
|
13
|
+
readOnlyHint: true,
|
|
14
|
+
destructiveHint: false,
|
|
15
|
+
idempotentHint: true,
|
|
16
|
+
openWorldHint: true,
|
|
17
|
+
},
|
|
18
|
+
inputSchema: z.object({
|
|
19
|
+
skill: z.string().describe("ID da skill (ex: 'page-builder', 'onboarding', 'motion')"),
|
|
20
|
+
projectId: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("ID do projeto pra injetar contexto do plano de produto (opcional)"),
|
|
24
|
+
}),
|
|
25
|
+
}, async ({ skill, projectId }) => {
|
|
26
|
+
// 1. Tentar composicao
|
|
27
|
+
const context = await extractProjectContext(process.cwd());
|
|
28
|
+
const composeBody = { skillName: skill, projectId, context };
|
|
29
|
+
const composed = await apiPost("/api/mcp/compose-skill", composeBody);
|
|
30
|
+
if (composed.ok && composed.data?.prompt) {
|
|
31
|
+
const d = composed.data;
|
|
32
|
+
const lines = [
|
|
33
|
+
`Skill: ${d.skillName}`,
|
|
34
|
+
`Fonte: composed (template v${d.templateVersion}, ${d.craftRulesCount} craft rules)`,
|
|
35
|
+
"",
|
|
36
|
+
"---",
|
|
37
|
+
"",
|
|
38
|
+
d.prompt,
|
|
39
|
+
];
|
|
40
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
41
|
+
}
|
|
42
|
+
// 2. Fallback: GET prompt cru
|
|
43
|
+
const params = { skill };
|
|
44
|
+
if (projectId)
|
|
45
|
+
params.projectId = projectId;
|
|
46
|
+
const response = await apiGet("/api/mcp/skill-prompt", params);
|
|
47
|
+
if (!response.ok || !response.data) {
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: `Erro ao buscar prompt: ${composed.error ?? response.error ?? "Sem resposta do servidor"}`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const d = response.data;
|
|
58
|
+
const lines = [
|
|
59
|
+
`Skill: ${d.skillName} (${d.skillId})`,
|
|
60
|
+
`Fonte: fallback (${d.source})`,
|
|
61
|
+
"",
|
|
62
|
+
"---",
|
|
63
|
+
"",
|
|
64
|
+
d.prompt,
|
|
65
|
+
];
|
|
66
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool refine_get_skill: retorna skill ativa + metadata + contexto PRD.
|
|
3
|
+
* A IA do IDE usa isso pra informar o builder onde esta no pipeline.
|
|
4
|
+
*/
|
|
5
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
export declare function registerGetSkillTool(server: McpServer): void;
|