agents.dev 1.4.0 → 1.5.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/package.json +1 -1
- package/src/index.js +123 -145
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const fsp = require('fs/promises');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const { intro, outro, multiselect,
|
|
6
|
+
const { intro, outro, multiselect, spinner, note } = require('@clack/prompts');
|
|
7
7
|
const pc = require('picocolors');
|
|
8
8
|
|
|
9
9
|
// Módulos Internos
|
|
@@ -24,58 +24,42 @@ async function main() {
|
|
|
24
24
|
console.clear();
|
|
25
25
|
intro(pc.bgMagenta(pc.white(' UNIVERSAL SPEC CLI ')));
|
|
26
26
|
|
|
27
|
-
// 1.
|
|
28
|
-
const
|
|
29
|
-
|
|
27
|
+
// 1. Scaffold Automático (Sempre executa)
|
|
28
|
+
const created = generateWorkflowGuide(process.cwd());
|
|
29
|
+
if (created) {
|
|
30
|
+
console.log(pc.green('✔ Estrutura de pastas (docs/) verificada.'));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 2. Seleção de Ferramentas (Múltipla escolha)
|
|
34
|
+
const tools = await multiselect({
|
|
35
|
+
message: 'Para quais ferramentas você deseja instalar os Agentes?',
|
|
30
36
|
options: [
|
|
31
|
-
{ value: '
|
|
32
|
-
{ value: '
|
|
37
|
+
{ value: 'gemini', label: 'Gemini CLI', hint: '.gemini/commands/dev' },
|
|
38
|
+
{ value: 'roo', label: 'Roo Code', hint: '.roo/ & custom_modes.json' },
|
|
39
|
+
{ value: 'cline', label: 'Cline', hint: '.cline/ & custom_modes.json' },
|
|
40
|
+
{ value: 'cursor', label: 'Cursor', hint: '.cursor/rules/*.mdc' },
|
|
41
|
+
{ value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },
|
|
42
|
+
{ value: 'trae', label: 'Trae IDE', hint: '.trae/instructions.md' },
|
|
43
|
+
{ value: 'kilo', label: 'Kilo Code', hint: '.kilo/prompts/*.md' },
|
|
44
|
+
{ value: 'copilot', label: 'GitHub Copilot', hint: '.github/copilot-instructions.md' },
|
|
45
|
+
{ value: 'web', label: 'OpenAI / Claude', hint: 'prompts/*.txt' },
|
|
46
|
+
{ value: 'opencode', label: 'OpenCode', hint: '.opencode/*.md' },
|
|
33
47
|
],
|
|
34
48
|
required: true,
|
|
49
|
+
hint: 'Espaço para selecionar, Enter para confirmar'
|
|
35
50
|
});
|
|
36
51
|
|
|
37
|
-
if (!
|
|
38
|
-
outro('Operação cancelada.');
|
|
52
|
+
if (!tools || tools.length === 0) {
|
|
53
|
+
outro('Nenhuma ferramenta selecionada. Operação cancelada.');
|
|
39
54
|
process.exit(0);
|
|
40
55
|
}
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
if (components.includes('docs')) {
|
|
44
|
-
const created = generateWorkflowGuide(process.cwd());
|
|
45
|
-
if (created) {
|
|
46
|
-
note('Documentação criada em docs/README.md', 'Docs');
|
|
47
|
-
} else {
|
|
48
|
-
console.log(pc.gray('ℹ️ Pasta docs/ já existe. Ignorando criação.'));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// 3. Instalação de Agentes
|
|
53
|
-
if (components.includes('agents')) {
|
|
54
|
-
const tool = await select({
|
|
55
|
-
message: 'Onde você deseja instalar os Agentes?',
|
|
56
|
-
options: [
|
|
57
|
-
{ value: 'gemini', label: 'Gemini CLI', hint: '.gemini/commands/dev' },
|
|
58
|
-
{ value: 'roo', label: 'Roo Code', hint: '.roo/ & custom_modes.json' },
|
|
59
|
-
{ value: 'cline', label: 'Cline', hint: '.cline/ & custom_modes.json' },
|
|
60
|
-
{ value: 'cursor', label: 'Cursor', hint: '.cursor/rules/*.mdc' },
|
|
61
|
-
{ value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },
|
|
62
|
-
{ value: 'trae', label: 'Trae IDE', hint: '.trae/instructions.md' },
|
|
63
|
-
{ value: 'kilo', label: 'Kilo Code', hint: '.kilo/prompts/*.md' },
|
|
64
|
-
{ value: 'copilot', label: 'GitHub Copilot', hint: '.github/copilot-instructions.md' },
|
|
65
|
-
{ value: 'web', label: 'OpenAI / Claude', hint: 'prompts/*.txt (Copiar & Colar)' },
|
|
66
|
-
{ value: 'opencode', label: 'OpenCode', hint: '.opencode/*.md' },
|
|
67
|
-
],
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
if (!tool) process.exit(0);
|
|
71
|
-
|
|
72
|
-
await processAgentsInstallation(tool);
|
|
73
|
-
}
|
|
57
|
+
await processAgentsInstallation(tools);
|
|
74
58
|
|
|
75
59
|
outro(pc.green('Configuração concluída com sucesso! 🚀'));
|
|
76
60
|
}
|
|
77
61
|
|
|
78
|
-
async function processAgentsInstallation(
|
|
62
|
+
async function processAgentsInstallation(tools) {
|
|
79
63
|
const s = spinner();
|
|
80
64
|
s.start('Carregando definições...');
|
|
81
65
|
|
|
@@ -87,114 +71,108 @@ async function processAgentsInstallation(tool) {
|
|
|
87
71
|
return;
|
|
88
72
|
}
|
|
89
73
|
|
|
90
|
-
s.message(`Instalando
|
|
91
|
-
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
const targetDir = path.join(process.cwd(), '.gemini', 'commands', 'dev');
|
|
95
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
96
|
-
|
|
97
|
-
await Promise.all(validAgents.map(agent => {
|
|
98
|
-
const toml = toGeminiTOML(agent);
|
|
99
|
-
// Usa originalName para manter pontos (dev.coder.toml)
|
|
100
|
-
const fileName = `${agent.originalName}.toml`;
|
|
101
|
-
return fsp.writeFile(path.join(targetDir, fileName), toml);
|
|
102
|
-
}));
|
|
103
|
-
}
|
|
104
|
-
else if (tool === 'roo' || tool === 'cline') {
|
|
105
|
-
const configDir = tool === 'roo' ? '.roo' : '.cline';
|
|
106
|
-
const targetDir = path.join(process.cwd(), configDir);
|
|
107
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
108
|
-
|
|
109
|
-
// 1. Gera arquivos Markdown (Contexto)
|
|
110
|
-
await Promise.all(validAgents.map(agent => {
|
|
111
|
-
const md = toKiloMarkdown(agent); // Reutiliza formato Markdown padrão
|
|
112
|
-
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
113
|
-
}));
|
|
114
|
-
|
|
115
|
-
// 2. Gera JSON para Custom Modes (Configuração da Extensão)
|
|
116
|
-
const modes = validAgents.map(agent => toRooConfig(agent, agent.slug));
|
|
117
|
-
const jsonContent = JSON.stringify({ customModes: modes }, null, 2);
|
|
118
|
-
const fileName = `${tool}_custom_modes.json`;
|
|
119
|
-
await fsp.writeFile(path.join(process.cwd(), fileName), jsonContent);
|
|
120
|
-
|
|
121
|
-
note(`1. Arquivos de contexto salvos em '${configDir}/'\n2. Copie o conteúdo de '${fileName}' para configurar os modos na extensão.`, 'Configuração Híbrida');
|
|
122
|
-
}
|
|
123
|
-
else if (tool === 'kilo') {
|
|
124
|
-
const targetDir = path.join(process.cwd(), '.kilo', 'prompts');
|
|
125
|
-
await fsp.mkdir(targetDir, { recursive: true });
|
|
126
|
-
|
|
127
|
-
await Promise.all(validAgents.map(agent => {
|
|
128
|
-
const md = toKiloMarkdown(agent);
|
|
129
|
-
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
else if (tool === 'copilot') {
|
|
133
|
-
const githubDir = path.join(process.cwd(), '.github');
|
|
134
|
-
const agentsDir = path.join(githubDir, 'agents');
|
|
135
|
-
await fsp.mkdir(agentsDir, { recursive: true });
|
|
136
|
-
|
|
137
|
-
// 1. Gera todos os agentes individuais
|
|
138
|
-
await Promise.all(validAgents.map(agent => {
|
|
139
|
-
const md = toCopilotInstructions(agent);
|
|
140
|
-
return fsp.writeFile(path.join(agentsDir, `${agent.slug}.md`), md);
|
|
141
|
-
}));
|
|
142
|
-
|
|
143
|
-
// 2. Define o copilot-instructions.md principal
|
|
144
|
-
// Tenta achar o 'dev.coder' ou usa o primeiro da lista
|
|
145
|
-
const mainAgent = validAgents.find(a => a.slug.includes('coder')) || validAgents[0];
|
|
146
|
-
const mainInstructions = toCopilotInstructions(mainAgent);
|
|
147
|
-
|
|
148
|
-
await fsp.writeFile(path.join(githubDir, 'copilot-instructions.md'), mainInstructions);
|
|
149
|
-
note(`Agente principal (${mainAgent.name}) definido em .github/copilot-instructions.md\nOutros agentes salvos em .github/agents/`, 'Configuração Copilot');
|
|
150
|
-
}
|
|
151
|
-
else if (tool === 'cursor') {
|
|
152
|
-
const rulesDir = path.join(process.cwd(), '.cursor', 'rules');
|
|
153
|
-
await fsp.mkdir(rulesDir, { recursive: true });
|
|
154
|
-
|
|
155
|
-
await Promise.all(validAgents.map(agent => {
|
|
156
|
-
const mdc = toCursorMDC(agent);
|
|
157
|
-
return fsp.writeFile(path.join(rulesDir, `${agent.slug}.mdc`), mdc);
|
|
158
|
-
}));
|
|
159
|
-
note(`Regras salvas em .cursor/rules/*.mdc`, 'Configuração Cursor');
|
|
160
|
-
}
|
|
161
|
-
else if (tool === 'windsurf') {
|
|
162
|
-
const mainAgent = validAgents.find(a => a.slug.includes('coder')) || validAgents[0];
|
|
163
|
-
const rules = toWindsurfRules(mainAgent);
|
|
164
|
-
await fsp.writeFile(path.join(process.cwd(), '.windsurfrules'), rules);
|
|
165
|
-
note(`Regras salvas em .windsurfrules usando o perfil do agente ${mainAgent.name}`, 'Configuração Windsurf');
|
|
166
|
-
}
|
|
167
|
-
else if (tool === 'trae') {
|
|
168
|
-
const traeDir = path.join(process.cwd(), '.trae');
|
|
169
|
-
await fsp.mkdir(traeDir, { recursive: true });
|
|
74
|
+
s.message(`Instalando agentes para: ${tools.join(', ')}...`);
|
|
75
|
+
|
|
76
|
+
// Itera sobre cada ferramenta selecionada
|
|
77
|
+
for (const tool of tools) {
|
|
170
78
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
79
|
+
// Instalação Específica por Ferramenta
|
|
80
|
+
if (tool === 'gemini') {
|
|
81
|
+
const targetDir = path.join(process.cwd(), '.gemini', 'commands', 'dev');
|
|
82
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
83
|
+
|
|
84
|
+
await Promise.all(validAgents.map(agent => {
|
|
85
|
+
const toml = toGeminiTOML(agent);
|
|
86
|
+
const fileName = `${agent.originalName}.toml`;
|
|
87
|
+
return fsp.writeFile(path.join(targetDir, fileName), toml);
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
else if (tool === 'roo' || tool === 'cline') {
|
|
91
|
+
const configDir = tool === 'roo' ? '.roo' : '.cline';
|
|
92
|
+
const targetDir = path.join(process.cwd(), configDir);
|
|
93
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
94
|
+
|
|
95
|
+
await Promise.all(validAgents.map(agent => {
|
|
96
|
+
const md = toKiloMarkdown(agent);
|
|
97
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
const modes = validAgents.map(agent => toRooConfig(agent, agent.slug));
|
|
101
|
+
const jsonContent = JSON.stringify({ customModes: modes }, null, 2);
|
|
102
|
+
const fileName = `${tool}_custom_modes.json`;
|
|
103
|
+
await fsp.writeFile(path.join(process.cwd(), fileName), jsonContent);
|
|
104
|
+
}
|
|
105
|
+
else if (tool === 'kilo') {
|
|
106
|
+
const targetDir = path.join(process.cwd(), '.kilo', 'prompts');
|
|
107
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
108
|
+
|
|
109
|
+
await Promise.all(validAgents.map(agent => {
|
|
110
|
+
const md = toKiloMarkdown(agent);
|
|
111
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
else if (tool === 'copilot') {
|
|
115
|
+
const githubDir = path.join(process.cwd(), '.github');
|
|
116
|
+
const agentsDir = path.join(githubDir, 'agents');
|
|
117
|
+
await fsp.mkdir(agentsDir, { recursive: true });
|
|
118
|
+
|
|
119
|
+
await Promise.all(validAgents.map(agent => {
|
|
120
|
+
const md = toCopilotInstructions(agent);
|
|
121
|
+
return fsp.writeFile(path.join(agentsDir, `${agent.slug}.md`), md);
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
const mainAgent = validAgents.find(a => a.slug.includes('coder')) || validAgents[0];
|
|
125
|
+
const mainInstructions = toCopilotInstructions(mainAgent);
|
|
126
|
+
await fsp.writeFile(path.join(githubDir, 'copilot-instructions.md'), mainInstructions);
|
|
127
|
+
}
|
|
128
|
+
else if (tool === 'cursor') {
|
|
129
|
+
const rulesDir = path.join(process.cwd(), '.cursor', 'rules');
|
|
130
|
+
await fsp.mkdir(rulesDir, { recursive: true });
|
|
131
|
+
|
|
132
|
+
await Promise.all(validAgents.map(agent => {
|
|
133
|
+
const mdc = toCursorMDC(agent);
|
|
134
|
+
return fsp.writeFile(path.join(rulesDir, `${agent.slug}.mdc`), mdc);
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
else if (tool === 'windsurf') {
|
|
138
|
+
const mainAgent = validAgents.find(a => a.slug.includes('coder')) || validAgents[0];
|
|
139
|
+
const rules = toWindsurfRules(mainAgent);
|
|
140
|
+
await fsp.writeFile(path.join(process.cwd(), '.windsurfrules'), rules);
|
|
141
|
+
}
|
|
142
|
+
else if (tool === 'trae') {
|
|
143
|
+
const traeDir = path.join(process.cwd(), '.trae');
|
|
144
|
+
await fsp.mkdir(traeDir, { recursive: true });
|
|
145
|
+
|
|
146
|
+
const mainAgent = validAgents.find(a => a.slug.includes('coder')) || validAgents[0];
|
|
147
|
+
const rules = toTraeRules(mainAgent);
|
|
148
|
+
await fsp.writeFile(path.join(traeDir, 'instructions.md'), rules);
|
|
149
|
+
}
|
|
150
|
+
else if (tool === 'web') {
|
|
151
|
+
const targetDir = path.join(process.cwd(), 'prompts');
|
|
152
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
153
|
+
|
|
154
|
+
await Promise.all(validAgents.map(agent => {
|
|
155
|
+
const txt = toPlainSystemPrompt(agent);
|
|
156
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.txt`), txt);
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
else if (tool === 'opencode') {
|
|
160
|
+
const targetDir = path.join(process.cwd(), '.opencode');
|
|
161
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
162
|
+
|
|
163
|
+
await Promise.all(validAgents.map(agent => {
|
|
164
|
+
const md = toKiloMarkdown(agent);
|
|
165
|
+
return fsp.writeFile(path.join(targetDir, `${agent.slug}.md`), md);
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
195
168
|
}
|
|
196
169
|
|
|
197
170
|
s.stop('Instalação finalizada!');
|
|
171
|
+
|
|
172
|
+
// Feedback consolidado
|
|
173
|
+
if (tools.includes('roo') || tools.includes('cline')) {
|
|
174
|
+
note('Lembre-se de configurar os Custom Modes no settings.json para Roo/Cline.', 'Aviso');
|
|
175
|
+
}
|
|
198
176
|
|
|
199
177
|
} catch (e) {
|
|
200
178
|
s.stop('Falha');
|