agents.dev 1.0.8 → 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/README.md CHANGED
@@ -1,17 +1,23 @@
1
1
  # agents-dev (Universal Spec CLI)
2
2
 
3
- Ferramenta CLI para configurar automaticamente o ambiente de desenvolvimento e instalar agentes de IA (Auditor, Coder, etc.) para diversas ferramentas como Gemini CLI, Roo Code, Cline e Kilo Code.
3
+ Ferramenta CLI para configurar automaticamente o ambiente de desenvolvimento e instalar agentes de IA (Auditor, Coder, etc.) para diversas ferramentas modernas de IA.
4
4
 
5
5
  ## Funcionalidades
6
6
 
7
7
  ### 1. Instalação de Agentes de IA
8
8
  Lê definições agnósticas (YAML) e converte para formatos específicos:
9
9
  * **Gemini CLI:** Gera arquivos de configuração `.toml`.
10
- * **Roo Code / Cline:** Gera modos customizados (`_custom_modes.json`).
10
+ * **Roo Code / Cline:** Gera modos customizados (`_custom_modes.json`) e regras de contexto em `.roo/` ou `.cline/`.
11
+ * **GitHub Copilot:** Gera instruções em `.github/copilot-instructions.md` e agentes em `.github/agents/`.
12
+ * **Cursor:** Gera regras em `.cursor/rules/*.mdc`.
13
+ * **Windsurf:** Gera regras em `.windsurfrules`.
14
+ * **Trae:** Gera instruções em `.trae/instructions.md`.
15
+ * **OpenCode:** Gera agentes em `.opencode/`.
16
+ * **OpenAI / Claude (Web):** Gera prompts em texto puro na pasta `prompts/`.
11
17
  * **Kilo Code:** Gera prompts em Markdown (`.kilo/prompts/*.md`).
12
18
 
13
- ### 2. Configuração
14
- Automatiza a criação de arquivos de configuração necessários para integrar agentes de IA ao seu fluxo de trabalho.
19
+ ### 2. Configuração de Workflow
20
+ Automatiza a criação da estrutura de documentação (`docs/` e `docs/logs/`) para suportar o fluxo de trabalho dos agentes.
15
21
 
16
22
  ## Instalação e Uso
17
23
 
@@ -20,6 +26,7 @@ Você pode executar a ferramenta diretamente via `npx` sem instalação prévia:
20
26
  ```bash
21
27
  npx agents-dev
22
28
  ```
29
+ *(ou `npx agents.dev`)*
23
30
 
24
31
  Ou instalar globalmente:
25
32
 
@@ -31,8 +38,8 @@ agents-dev
31
38
  ## Como funciona
32
39
 
33
40
  1. Execute `npx agents-dev` na raiz do seu projeto.
34
- 2. A interface interativa perguntará quais configurações você deseja aplicar.
35
- 3. Os arquivos de configuração dos agentes serão gerados na pasta do seu projeto.
41
+ 2. A interface interativa perguntará quais configurações você deseja aplicar e para qual ferramenta.
42
+ 3. Os arquivos de configuração dos agentes serão gerados na pasta do seu projeto automaticamente.
36
43
 
37
44
  ## Estrutura do Projeto
38
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents.dev",
3
- "version": "1.0.8",
3
+ "version": "1.5.0",
4
4
  "description": "Instalador automático dos agentes de desenvolvimento",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -1,134 +1,178 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const fs = require('fs');
4
+ const fsp = require('fs/promises');
4
5
  const path = require('path');
5
- const yaml = require('js-yaml');
6
- const { intro, outro, multiselect, select, spinner, note } = require('@clack/prompts');
6
+ const { intro, outro, multiselect, spinner, note } = require('@clack/prompts');
7
7
  const pc = require('picocolors');
8
8
 
9
9
  // Módulos Internos
10
- const { AgentSchema } = require('./lib/schema');
11
- const { toGeminiTOML, toRooConfig, toKiloMarkdown } = require('./lib/transformers');
10
+ const { loadAgents } = require('./lib/agents');
11
+ const {
12
+ toGeminiTOML,
13
+ toRooConfig,
14
+ toKiloMarkdown,
15
+ toCopilotInstructions,
16
+ toCursorMDC,
17
+ toWindsurfRules,
18
+ toPlainSystemPrompt,
19
+ toTraeRules
20
+ } = require('./lib/transformers');
12
21
  const { generateWorkflowGuide } = require('./lib/docs');
13
22
 
14
23
  async function main() {
15
24
  console.clear();
16
25
  intro(pc.bgMagenta(pc.white(' UNIVERSAL SPEC CLI ')));
17
26
 
18
- // 1. Seleção de Componentes
19
- const components = await multiselect({
20
- message: 'O que você deseja configurar?',
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?',
21
36
  options: [
22
- { value: 'docs', label: 'Gerar Documentação de Workflow (docs/README.md)', hint: 'Essencial' },
23
- { value: 'agents', label: 'Instalar Agentes de IA', hint: 'Recomendado' },
24
- { value: 'vscode', label: 'Configurar VS Code', hint: '(Simulado)' },
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' },
25
47
  ],
26
48
  required: true,
49
+ hint: 'Espaço para selecionar, Enter para confirmar'
27
50
  });
28
51
 
29
- if (!components) {
30
- outro('Operação cancelada.');
52
+ if (!tools || tools.length === 0) {
53
+ outro('Nenhuma ferramenta selecionada. Operação cancelada.');
31
54
  process.exit(0);
32
55
  }
33
56
 
34
- // 2. Instalação de Documentação
35
- if (components.includes('docs')) {
36
- const created = generateWorkflowGuide(process.cwd());
37
- if (created) {
38
- note('Documentação criada em docs/README.md', 'Docs');
39
- } else {
40
- console.log(pc.gray('ℹ️ Pasta docs/ já existe. Ignorando criação.'));
41
- }
42
- }
43
-
44
- // 3. Instalação de Agentes
45
- if (components.includes('agents')) {
46
- const tool = await select({
47
- message: 'Onde você deseja instalar os Agentes?',
48
- options: [
49
- { value: 'gemini', label: 'Gemini CLI', hint: '.gemini/commands/dev' },
50
- { value: 'roo', label: 'Roo Code', hint: 'Gera roo_custom_modes.json' },
51
- { value: 'cline', label: 'Cline', hint: 'Gera cline_custom_modes.json' },
52
- { value: 'kilo', label: 'Kilo Code', hint: '.kilo/prompts/*.md' },
53
- ],
54
- });
55
-
56
- if (!tool) process.exit(0);
57
-
58
- await processAgentsInstallation(tool);
59
- }
57
+ await processAgentsInstallation(tools);
60
58
 
61
59
  outro(pc.green('Configuração concluída com sucesso! 🚀'));
62
60
  }
63
61
 
64
- async function processAgentsInstallation(tool) {
62
+ async function processAgentsInstallation(tools) {
65
63
  const s = spinner();
66
64
  s.start('Carregando definições...');
67
65
 
68
- const definitionsDir = path.join(__dirname, '..', 'definitions');
69
- if (!fs.existsSync(definitionsDir)) {
70
- s.stop('Falha');
71
- note(`Pasta de definições não encontrada: ${definitionsDir}`, 'Erro Fatal');
72
- return;
73
- }
74
-
75
- const files = fs.readdirSync(definitionsDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
76
- const validAgents = [];
77
-
78
- // Validação e Carregamento
79
- for (const file of files) {
80
- try {
81
- const content = fs.readFileSync(path.join(definitionsDir, file), 'utf8');
82
- const raw = yaml.load(content);
83
-
84
- // Validação com Zod
85
- const parsed = AgentSchema.safeParse(raw);
86
- if (!parsed.success) {
87
- console.warn(pc.yellow(`⚠️ Ignorando ${file}: Inválido`));
88
- continue;
89
- }
90
-
91
- const agent = parsed.data;
92
- agent.slug = file.replace(/\.ya?ml$/, '').replace(/\./g, '-'); // dev.coder -> dev-coder
93
- validAgents.push(agent);
66
+ try {
67
+ const validAgents = await loadAgents();
94
68
 
95
- } catch (e) {
96
- console.error(pc.red(`Erro ao ler ${file}: ${e.message}`));
69
+ if (validAgents.length === 0) {
70
+ s.stop('Nenhum agente válido encontrado.');
71
+ return;
97
72
  }
98
- }
99
73
 
100
- s.message(`Instalando ${validAgents.length} agentes para ${tool}...`);
74
+ s.message(`Instalando agentes para: ${tools.join(', ')}...`);
101
75
 
102
- // Instalação Específica por Ferramenta
103
- try {
104
- if (tool === 'gemini') {
105
- const targetDir = path.join(process.cwd(), '.gemini', 'commands', 'dev');
106
- if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
107
-
108
- for (const agent of validAgents) {
109
- const toml = toGeminiTOML(agent);
110
- // Nome original com pontos (dev.coder.toml) é preferível para Gemini CLI
111
- const fileName = `${agent.slug.replace(/-/g, '.')}.toml`;
112
- fs.writeFileSync(path.join(targetDir, fileName), toml);
76
+ // Itera sobre cada ferramenta selecionada
77
+ for (const tool of tools) {
78
+
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);
113
127
  }
114
- }
115
- else if (tool === 'roo' || tool === 'cline') {
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
- fs.writeFileSync(path.join(process.cwd(), fileName), jsonContent);
120
- note(`Copie o conteúdo de '${fileName}' para as configurações da extensão.`, 'Ação Manual');
121
- }
122
- else if (tool === 'kilo') {
123
- const targetDir = path.join(process.cwd(), '.kilo', 'prompts');
124
- if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
125
-
126
- for (const agent of validAgents) {
127
- const md = toKiloMarkdown(agent);
128
- fs.writeFileSync(path.join(targetDir, `${agent.slug}.md`), md);
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
+ }));
129
167
  }
130
168
  }
169
+
131
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
+ }
132
176
 
133
177
  } catch (e) {
134
178
  s.stop('Falha');
@@ -0,0 +1,68 @@
1
+ const fs = require('fs/promises');
2
+ const path = require('path');
3
+ const yaml = require('js-yaml');
4
+ const { AgentSchema } = require('./schema');
5
+ const pc = require('picocolors');
6
+
7
+ /**
8
+ * Carrega e valida todas as definições de agentes da pasta definitions
9
+ * @returns {Promise<Array>} Lista de agentes validados
10
+ */
11
+ async function loadAgents() {
12
+ const definitionsDir = path.join(__dirname, '..', '..', 'definitions');
13
+
14
+ try {
15
+ await fs.access(definitionsDir);
16
+ } catch {
17
+ throw new Error(`Pasta de definições não encontrada: ${definitionsDir}`);
18
+ }
19
+
20
+ const files = await fs.readdir(definitionsDir);
21
+ const yamlFiles = files.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
22
+
23
+ // Leitura e processamento em paralelo
24
+ const results = await Promise.all(yamlFiles.map(async (file) => {
25
+ try {
26
+ const content = await fs.readFile(path.join(definitionsDir, file), 'utf8');
27
+ const raw = yaml.load(content);
28
+
29
+ const parsed = AgentSchema.safeParse(raw);
30
+ if (!parsed.success) {
31
+ return {
32
+ success: false,
33
+ file,
34
+ error: 'Validação do Schema falhou',
35
+ details: parsed.error.format()
36
+ };
37
+ }
38
+
39
+ const agent = parsed.data;
40
+ // Normaliza o slug: dev.coder -> dev-coder
41
+ agent.slug = file.replace(/\.ya?ml$/, '').replace(/\./g, '-');
42
+ // Mantém o nome original do arquivo para referência (útil para Gemini CLI)
43
+ agent.originalName = file.replace(/\.ya?ml$/, '');
44
+
45
+ return { success: true, agent };
46
+
47
+ } catch (e) {
48
+ return { success: false, file, error: e.message };
49
+ }
50
+ }));
51
+
52
+ // Separa sucessos e falhas
53
+ const validAgents = [];
54
+ const errors = [];
55
+
56
+ results.forEach(res => {
57
+ if (res.success) {
58
+ validAgents.push(res.agent);
59
+ } else {
60
+ errors.push(res);
61
+ console.warn(pc.yellow(`⚠️ Ignorando ${res.file}: ${res.error}`));
62
+ }
63
+ });
64
+
65
+ return validAgents;
66
+ }
67
+
68
+ module.exports = { loadAgents };
package/src/lib/docs.js CHANGED
@@ -3,12 +3,18 @@ const path = require('path');
3
3
  const pc = require('picocolors');
4
4
 
5
5
  /**
6
- * Gera o guia de workflow do projeto
6
+ * Gera o guia de workflow e a estrutura de pastas necessária para os agentes
7
7
  */
8
8
  function generateWorkflowGuide(baseDir) {
9
9
  const docsDir = path.join(baseDir, 'docs');
10
+ const logsDir = path.join(docsDir, 'logs');
10
11
 
11
- // Conteúdo baseado no exemplo provided
12
+ // Cria a estrutura de pastas recursivamente (Funciona em Windows, Mac e Linux)
13
+ if (!fs.existsSync(logsDir)) {
14
+ fs.mkdirSync(logsDir, { recursive: true });
15
+ }
16
+
17
+ // Conteúdo do README.md
12
18
  const content = `# 🤖 Agent Workflow Guide
13
19
 
14
20
  Este documento descreve o fluxo de desenvolvimento padrão usando os Agentes instalados.
@@ -86,12 +92,13 @@ O sistema segue um processo **Waterfall** para planejamento (precisão) e **Iter
86
92
  \`changelog.md\`
87
93
  `;
88
94
 
89
- if (!fs.existsSync(docsDir)) {
90
- fs.mkdirSync(docsDir, { recursive: true });
91
- fs.writeFileSync(path.join(docsDir, 'README.md'), content);
95
+ const readmePath = path.join(docsDir, 'README.md');
96
+ if (!fs.existsSync(readmePath)) {
97
+ fs.writeFileSync(readmePath, content);
92
98
  return true;
93
99
  }
94
- return false;
100
+
101
+ return true; // Retorna true indicando que a estrutura foi garantida
95
102
  }
96
103
 
97
104
  module.exports = { generateWorkflowGuide };
@@ -86,4 +86,114 @@ function toKiloMarkdown(agent) {
86
86
  return parts.join('\n');
87
87
  }
88
88
 
89
- module.exports = { toGeminiTOML, toRooConfig, toKiloMarkdown };
89
+ /**
90
+ * Converte para Instruções do GitHub Copilot (.github/copilot-instructions.md)
91
+ */
92
+ function toCopilotInstructions(agent) {
93
+ const parts = [
94
+ `<!-- GitHub Copilot Instructions for ${agent.name} -->`,
95
+ `# Identity and Role`,
96
+ `You are **${agent.name}** ${agent.emoji}.`,
97
+ `**Role**: ${agent.role}`,
98
+ `\n## Core Instructions`,
99
+ agent.systemPrompt.trim(),
100
+ '\n'
101
+ ];
102
+
103
+ if (agent.rules && agent.rules.length > 0) {
104
+ parts.push(`## Rules & Guidelines`);
105
+ agent.rules.forEach(rule => parts.push(`- ${rule}`));
106
+ }
107
+
108
+ // Adiciona uma seção de estilo de resposta para garantir conformidade
109
+ parts.push(`\n## Response Style`);
110
+ parts.push(`- Be concise and objective.`);
111
+ parts.push(`- Use Portuguese (Brazil) unless told otherwise.`);
112
+ parts.push(`- Follow the project conventions defined in the workspace.`);
113
+
114
+ return parts.join('\n');
115
+ }
116
+
117
+ /**
118
+ * Converte para Cursor Rules (.mdc)
119
+ * Inclui Frontmatter para Contexto
120
+ */
121
+ function toCursorMDC(agent) {
122
+ // Tenta inferir globs baseados no papel do agente
123
+ let globs = "*";
124
+ const roleLower = agent.slug.toLowerCase();
125
+
126
+ if (roleLower.includes('test') || roleLower.includes('qa')) globs = "*.test.*, *.spec.*, **/tests/**";
127
+ if (roleLower.includes('css') || roleLower.includes('style')) globs = "*.css, *.scss, *.tailwind";
128
+ if (roleLower.includes('sql') || roleLower.includes('db')) globs = "*.sql, *.prisma, *.schema";
129
+
130
+ return `---
131
+ description: ${agent.description || agent.role}
132
+ globs: ${globs}
133
+ ---
134
+ # ${agent.name} ${agent.emoji}
135
+
136
+ Role: ${agent.role}
137
+
138
+ ## Instructions
139
+ ${agent.systemPrompt.trim()}
140
+
141
+ ${agent.rules && agent.rules.length > 0 ? '## Rules\n' + agent.rules.map(r => `- ${r}`).join('\n') : ''}
142
+ `;
143
+ }
144
+
145
+ /**
146
+ * Converte para Windsurf (.windsurfrules)
147
+ */
148
+ function toWindsurfRules(agent) {
149
+ return `# ${agent.name} ${agent.emoji} Rules
150
+
151
+ Role: ${agent.role}
152
+
153
+ ## Core Logic
154
+ ${agent.systemPrompt.trim()}
155
+
156
+ ${agent.rules && agent.rules.length > 0 ? '## Guidelines\n' + agent.rules.map(r => `- ${r}`).join('\n') : ''}
157
+ `;
158
+ }
159
+
160
+ /**
161
+ * Converte para System Prompt Puro (OpenAI/Claude/Web)
162
+ */
163
+ function toPlainSystemPrompt(agent) {
164
+ return `You are ${agent.name} ${agent.emoji}
165
+ Role: ${agent.role}
166
+
167
+ [SYSTEM INSTRUCTIONS]
168
+ ${agent.systemPrompt.trim()}
169
+
170
+ ${agent.rules && agent.rules.length > 0 ? '[GUIDELINES]\n' + agent.rules.map(r => `- ${r}`).join('\n') : ''}
171
+ `;
172
+ }
173
+
174
+ /**
175
+ * Converte para Trae Instructions
176
+ */
177
+ function toTraeRules(agent) {
178
+ return `<!-- Trae Workspace Rules -->
179
+ # ${agent.name} ${agent.emoji}
180
+
181
+ **Role**: ${agent.role}
182
+
183
+ ## Context & Instructions
184
+ ${agent.systemPrompt.trim()}
185
+
186
+ ${agent.rules && agent.rules.length > 0 ? '## Constraints\n' + agent.rules.map(r => `- ${r}`).join('\n') : ''}
187
+ `;
188
+ }
189
+
190
+ module.exports = {
191
+ toGeminiTOML,
192
+ toRooConfig,
193
+ toKiloMarkdown,
194
+ toCopilotInstructions,
195
+ toCursorMDC,
196
+ toWindsurfRules,
197
+ toPlainSystemPrompt,
198
+ toTraeRules
199
+ };