sdd-toolkit 1.1.0 → 1.6.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.
@@ -0,0 +1,188 @@
1
+ const fs = require('fs/promises');
2
+ const path = require('path');
3
+ const pc = require('picocolors');
4
+ const { t } = require('./i18n');
5
+
6
+ const DOCS_DIR = '.sdd-toolkit';
7
+ const PROJECT_FILE = path.join(DOCS_DIR, 'project.md');
8
+ const TASKS_FILE = path.join(DOCS_DIR, 'task.md');
9
+ const LOGS_DIR = path.join(DOCS_DIR, 'logs', 'executions');
10
+ const PACKAGE_FILE = 'package.json';
11
+
12
+ /**
13
+ * Extracts metadata from package.json (priority) or project.md
14
+ */
15
+ async function getProjectMetadata() {
16
+ let meta = { title: 'Project', version: '0.0.0', status: 'Active' };
17
+
18
+ // Try reading package.json first (Single Source of Truth for Version)
19
+ try {
20
+ const pkgContent = await fs.readFile(PACKAGE_FILE, 'utf8');
21
+ const pkg = JSON.parse(pkgContent);
22
+ if (pkg.name) meta.title = pkg.name;
23
+ if (pkg.version) meta.version = pkg.version;
24
+ } catch (e) {
25
+ // Ignore if no package.json
26
+ }
27
+
28
+ // Try reading project.md for status or title fallback
29
+ try {
30
+ const content = await fs.readFile(PROJECT_FILE, 'utf8');
31
+
32
+ // Only override title if package.json didn't provide one
33
+ if (meta.title === 'Project') {
34
+ const titleMatch = content.match(/title:\s*(.+)/);
35
+ if (titleMatch) meta.title = titleMatch[1].trim();
36
+ }
37
+
38
+ const statusMatch = content.match(/status:\s*(.+)/);
39
+ if (statusMatch) meta.status = statusMatch[1].trim();
40
+
41
+ } catch (e) {
42
+ // Ignore errors
43
+ }
44
+
45
+ return meta;
46
+ }
47
+
48
+ /**
49
+ * Parses task.md to calculate progress metrics
50
+ */
51
+ async function getTaskProgress() {
52
+ try {
53
+ const content = await fs.readFile(TASKS_FILE, 'utf8');
54
+
55
+ // Extract Milestone Name
56
+ const milestoneMatch = content.match(/# Execution Backlog:\s*(.+)/);
57
+ const milestone = milestoneMatch ? milestoneMatch[1].trim() : 'General Tasks';
58
+
59
+ // Count Checkboxes
60
+ const total = (content.match(/- \[ \]/g) || []).length + (content.match(/- \[x\]/g) || []).length;
61
+ const done = (content.match(/- \[x\]/g) || []).length;
62
+ const pending = total - done;
63
+ const percent = total > 0 ? Math.round((done / total) * 100) : 0;
64
+
65
+ return { milestone, total, done, pending, percent };
66
+ } catch (e) {
67
+ return { milestone: 'No active plan', total: 0, done: 0, pending: 0, percent: 0 };
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Retrieves the N most recent execution logs
73
+ */
74
+ async function getRecentLogs(limit = 5) {
75
+ try {
76
+ // Ensure dir exists to avoid crash
77
+ await fs.access(LOGS_DIR);
78
+
79
+ const files = await fs.readdir(LOGS_DIR);
80
+
81
+ // Read stats for sorting
82
+ const fileStats = await Promise.all(
83
+ files
84
+ .filter(f => f.endsWith('.md'))
85
+ .map(async (file) => {
86
+ const filePath = path.join(LOGS_DIR, file);
87
+ const stats = await fs.stat(filePath);
88
+ return { file, mtime: stats.mtime, filePath };
89
+ })
90
+ );
91
+
92
+ // Sort by time desc
93
+ const sorted = fileStats.sort((a, b) => b.mtime - a.mtime).slice(0, limit);
94
+
95
+ // Read content to get status/task ID if possible (simplified for now)
96
+ const logs = sorted.map(item => {
97
+ const name = item.file.replace('.md', '');
98
+ return {
99
+ name,
100
+ date: item.mtime.toLocaleDateString(),
101
+ status: 'Completed'
102
+ };
103
+ });
104
+
105
+ return logs;
106
+ } catch (e) {
107
+ return [];
108
+ }
109
+ }
110
+
111
+ /**
112
+ * UI Component: Progress Bar
113
+ * [██████░░░░] 60%
114
+ */
115
+ function drawProgressBar(percent, width = 20) {
116
+ const filled = Math.round((percent / 100) * width);
117
+ const empty = width - filled;
118
+
119
+ const bar = pc.green('█'.repeat(filled)) + pc.gray('░'.repeat(empty));
120
+ return `[${bar}] ${pc.bold(percent + '%')}`;
121
+ }
122
+
123
+ /**
124
+ * UI Component: Box
125
+ */
126
+ function drawBox(lines) {
127
+ const maxWidth = Math.max(60, ...lines.map(l => l.replace(/\x1b\[[0-9;]*m/g, '').length));
128
+ const borderTop = '╭' + '─'.repeat(maxWidth + 2) + '╮';
129
+ const borderBottom = '╰' + '─'.repeat(maxWidth + 2) + '╯';
130
+
131
+ console.log(pc.gray(borderTop));
132
+ lines.forEach(line => {
133
+ const len = line.replace(/\x1b\[[0-9;]*m/g, '').length;
134
+ const padding = ' '.repeat(maxWidth - len);
135
+ console.log(pc.gray('│ ') + line + padding + pc.gray(' │'));
136
+ });
137
+ console.log(pc.gray(borderBottom));
138
+ }
139
+
140
+ /**
141
+ * Main Render Function
142
+ */
143
+ async function renderDashboard() {
144
+ console.clear();
145
+
146
+ // Fetch Data Parallel
147
+ const [meta, progress, logs] = await Promise.all([
148
+ getProjectMetadata(),
149
+ getTaskProgress(),
150
+ getRecentLogs(5)
151
+ ]);
152
+
153
+ // Header (using i18n keys)
154
+ drawBox([
155
+ `${pc.magenta(t('DASHBOARD.TITLE'))} ${pc.bold(meta.title)} (v${meta.version})`,
156
+ `${pc.cyan(t('DASHBOARD.PHASE'))} ${progress.milestone}`,
157
+ `${pc.yellow(t('DASHBOARD.STATUS'))} ${meta.status}`
158
+ ]);
159
+
160
+ console.log(''); // Spacing
161
+
162
+ // Progress Section
163
+ console.log(pc.bold(t('DASHBOARD.OVERALL')));
164
+ console.log(drawProgressBar(progress.percent, 40));
165
+ console.log(`${pc.green('✅ ' + progress.done + ' ' + t('DASHBOARD.COMPLETED'))} | ${pc.red('⭕ ' + progress.pending + ' ' + t('DASHBOARD.PENDING'))}`);
166
+
167
+ console.log(''); // Spacing
168
+
169
+ // Recent Logs Section
170
+ if (logs.length > 0) {
171
+ console.log(pc.bold(t('DASHBOARD.RECENT')));
172
+ logs.forEach(log => {
173
+ console.log(`${pc.gray('•')} ${pc.dim(`[${log.date}]`)} ${log.name}`);
174
+ });
175
+ } else {
176
+ console.log(pc.gray(t('DASHBOARD.NO_ACTIVITY')));
177
+ }
178
+
179
+ console.log(''); // Spacing
180
+ console.log(pc.bgMagenta(pc.black(t('DASHBOARD.ACTION'))) + ' ' + t('DASHBOARD.HINT') + ' ' + pc.cyan('/dev:coder <Task_ID>') + ' ' + t('DASHBOARD.HINT_SUFFIX'));
181
+ }
182
+
183
+ module.exports = {
184
+ getProjectMetadata,
185
+ getTaskProgress,
186
+ getRecentLogs,
187
+ renderDashboard
188
+ };
package/src/lib/docs.js CHANGED
@@ -1,104 +1,69 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const pc = require('picocolors');
4
-
5
- /**
6
- * Gera o guia de workflow e a estrutura de pastas necessária para os agentes
7
- */
8
- function generateWorkflowGuide(baseDir) {
9
- const docsDir = path.join(baseDir, 'docs');
10
- const logsDir = path.join(docsDir, 'logs');
11
-
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
18
- const content = `# 🤖 Agent Workflow Guide
19
-
20
- Este documento descreve o fluxo de desenvolvimento padrão usando os Agentes instalados.
21
- O sistema segue um processo **Waterfall** para planejamento (precisão) e **Iterativo** para execução.
22
-
23
- ---
24
-
25
- ## 1. 🏗️ Project Spec (@Project Architect)
26
- **Role:** O Visionário.
27
- **Goal:** Traduzir sua ideia vaga em uma Especificação concreta com "Project Principles" definidos.
28
- - **Comando:** \\
29
- /dev:project "Eu quero um App de Todo que..."
30
- - **Saída:**
31
- \`docs/project.md\`
32
-
33
- ## 2. 🧱 Requirements Engineering (@Requirements Engineer)
34
- **Role:** O Tech Lead.
35
- **Goal:** Fechar decisões técnicas (Stack, Banco de Dados, Libs).
36
- - **Why?** Evita que o Coder "invente" arquitetura. Cria o "Contrato".
37
- - **Comando:**
38
- /dev:requirements
39
- - **Saída:**
40
- \`docs/requirements.md\`
41
-
42
- ## 3. 🗺️ Roadmap Strategy (@Milestone Manager)
43
- **Role:** O Estrategista.
44
- **Goal:** Fatiar o projeto em fases de entrega (MVPs).
45
- - **Comando:**
46
- /dev:milestone
47
- - **Saída:**
48
- \`docs/milestones.md\`
49
-
50
- ## 4. 📋 Task Planning (@Task Planner)
51
- **Role:** O Gerente.
52
- **Goal:** Quebrar um Milestone específico em tarefas atômicas para desenvolvedores.
53
- - **Why?** IAs falham com contextos gigantes. Tarefas pequenas = Código perfeito.
54
- - **Comando:**
55
- /dev:tasks <Milestone_ID>
56
- - **Saída:**
57
- \`docs/task.md\`
58
-
59
- ## 5. 🕵️ Blueprint Audit (@Auditor)
60
- **Role:** O Guardião.
61
- **Goal:** Validar consistência entre **Requirements** e **Tasks**.
62
- - **Comando:**
63
- /dev:auditor
64
- - **Saída:**
65
- \`audit_report.md\`
66
-
67
- ## 6. 💻 Implementation (@Coder)
68
- **Role:** O Construtor.
69
- **Goal:** Executar *uma tarefa por vez* do arquivo
70
- \`task.md\`.
71
- - **Comando:**
72
- /dev:coder <Task_ID>
73
- - **Buffer:**
74
- \`work_log.md\`
75
-
76
- ## 7. ⚖️ Quality Assurance (@QA Engineer)
77
- **Role:** O Inspetor.
78
- **Goal:** Verificar se a implementação bate com os Requisitos.
79
- - **Comando:**
80
- /dev:review <Task_ID>
81
- - **Saída:**
82
- \`docs/logs/review_log.md\`
83
-
84
- ## 8. 📦 Release Management (@Release Manager)
85
- **Role:** O Historiador.
86
- **Goal:** Consolidar o
87
- \`work_log.md\` em um
88
- \`changelog.md\` permanente.
89
- - **Comando:**
90
- /dev:log
91
- - **Saída:**
92
- \`changelog.md\`
93
- `;
94
-
95
- const readmePath = path.join(docsDir, 'README.md');
96
- if (!fs.existsSync(readmePath)) {
97
- fs.writeFileSync(readmePath, content);
98
- return true;
99
- }
100
-
101
- return true; // Retorna true indicando que a estrutura foi garantida
102
- }
103
-
104
- module.exports = { generateWorkflowGuide };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Generates the necessary folder structure for the agents
6
+ * Implements Smart Scaffolding: Only creates missing files/folders.
7
+ */
8
+ function generateWorkflowGuide(baseDir) {
9
+ const docsDir = path.join(baseDir, '.sdd-toolkit');
10
+
11
+ // 1. Define folder structure based on new logging architecture
12
+ const folders = [
13
+ path.join(docsDir, 'features'),
14
+ path.join(docsDir, 'logs'),
15
+ path.join(docsDir, 'logs', 'executions'),
16
+ path.join(docsDir, 'logs', 'reviews'),
17
+ path.join(docsDir, 'logs', 'archive'),
18
+ ];
19
+
20
+ let stats = { created: 0, verified: 0 };
21
+
22
+ // Create folders
23
+ folders.forEach(dir => {
24
+ if (!fs.existsSync(dir)) {
25
+ fs.mkdirSync(dir, { recursive: true });
26
+ stats.created++;
27
+ } else {
28
+ stats.verified++;
29
+ }
30
+ });
31
+
32
+ // 2. Define Templates Mapping
33
+ // Assumes templates are located in project_root/templates/
34
+ // __dirname is src/lib/, so templates is ../../templates
35
+ const templatesDir = path.join(__dirname, '..', '..', 'templates');
36
+
37
+ const templateFiles = [
38
+ { src: 'guidelines.md', dest: 'guidelines.md' },
39
+ { src: 'project.md', dest: 'project.md' },
40
+ { src: 'requirements.md', dest: 'requirements.md' },
41
+ { src: 'milestones.md', dest: 'milestones.md' },
42
+ { src: 'task.md', dest: 'task.md' }
43
+ ];
44
+
45
+ // Create files if they don't exist
46
+ templateFiles.forEach(tpl => {
47
+ const destPath = path.join(docsDir, tpl.dest);
48
+ if (!fs.existsSync(destPath)) {
49
+ try {
50
+ // Ensure template exists before reading
51
+ const templatePath = path.join(templatesDir, tpl.src);
52
+ if (fs.existsSync(templatePath)) {
53
+ const content = fs.readFileSync(templatePath, 'utf8');
54
+ fs.writeFileSync(destPath, content);
55
+ stats.created++;
56
+ }
57
+ } catch (e) {
58
+ // Fail silently/warn, do not crash the installer
59
+ console.warn(`Warning: Could not scaffold ${tpl.dest}`);
60
+ }
61
+ } else {
62
+ stats.verified++;
63
+ }
64
+ });
65
+
66
+ return stats;
67
+ }
68
+
69
+ module.exports = { generateWorkflowGuide };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Internal i18n Engine
3
+ */
4
+ const { TRANSLATIONS } = require('./messages');
5
+
6
+ let currentLocale = 'en';
7
+
8
+ function setLocale(locale) {
9
+ // Normalize logic (pt-br -> pt_br) if passed incorrectly, though prompts usually give controlled values
10
+ const normalized = locale.toLowerCase().replace('-', '_');
11
+
12
+ if (TRANSLATIONS[normalized]) {
13
+ currentLocale = normalized;
14
+ } else {
15
+ // Fallback to en
16
+ currentLocale = 'en';
17
+ }
18
+ }
19
+
20
+ function getLocale() {
21
+ return currentLocale;
22
+ }
23
+
24
+ /**
25
+ * Retrieves a string from the dictionary based on dot notation.
26
+ * e.g. t('INTRO.TITLE')
27
+ */
28
+ function t(path, ...args) {
29
+ const keys = path.split('.');
30
+ let value = TRANSLATIONS[currentLocale];
31
+
32
+ // Traverse the object for the current locale
33
+ for (const key of keys) {
34
+ if (value && value[key]) {
35
+ value = value[key];
36
+ } else {
37
+ value = undefined;
38
+ break;
39
+ }
40
+ }
41
+
42
+ // If not found, Try Fallback to EN
43
+ if (!value) {
44
+ let fallback = TRANSLATIONS['en'];
45
+ for (const k of keys) {
46
+ if (fallback && fallback[k]) fallback = fallback[k];
47
+ else {
48
+ fallback = undefined;
49
+ break;
50
+ }
51
+ }
52
+ value = fallback;
53
+ }
54
+
55
+ // If still not found, return the path itself as a debug marker
56
+ if (!value) return path;
57
+
58
+ if (typeof value === 'function') {
59
+ return value(...args);
60
+ }
61
+
62
+ return value;
63
+ }
64
+
65
+ module.exports = { t, setLocale, getLocale };
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Centralized User-Facing Strings
3
+ * Used for future Internationalization (i18n)
4
+ */
5
+
6
+ const EN = {
7
+ INTRO: {
8
+ TITLE: ' UNIVERSAL SPEC CLI ',
9
+ UPGRADE_TITLE: ' SDD TOOLKIT: UPGRADE MODE ',
10
+ },
11
+ GENERAL: {
12
+ CANCELLED: 'Operation cancelled.',
13
+ },
14
+ UPGRADE: {
15
+ NO_CONFIG: 'No existing configuration detected for upgrade. Starting standard installation.',
16
+ NO_CONFIG_TITLE: 'Info',
17
+ DETECTED_TOOLS: (tools) => `Tools detected: ${tools}`,
18
+ DETECTED_TITLE: 'Upgrading...',
19
+ SUCCESS: 'Agents updated successfully! 🚀',
20
+ },
21
+ SCAFFOLD: {
22
+ LOADING: 'Checking workspace structure...',
23
+ SUCCESS: '✔ Folder structure (.sdd-toolkit/) created.',
24
+ ALREADY_EXISTS: '✔ Folder structure (.sdd-toolkit/) verified.',
25
+ ERROR: 'Failed to verify workspace structure.',
26
+ },
27
+ SETUP: {
28
+ STACK_SELECT: 'What is your technology Stack profile?',
29
+ GLOBAL_RULES: 'Do you want to add any Global Rules for ALL agents?',
30
+ GLOBAL_RULES_HINT: 'Ex: Always reply in English; Use Conventional Commits...',
31
+ TOOL_SELECT: 'Which tools do you want to install the Agents for?',
32
+ TOOL_HINT: 'Space to select, Enter to confirm',
33
+ NO_TOOLS: 'No tools selected. Operation cancelled.',
34
+ SUCCESS: 'Setup completed successfully! 🚀',
35
+ },
36
+ INSTALL: {
37
+ LOADING: 'Loading definitions...',
38
+ NO_AGENTS: 'No valid agents found.',
39
+ INSTALLING: (tools) => `Installing agents for: ${tools}...`,
40
+ FINISHED: 'Installation finished!',
41
+ ROO_WARNING: 'Remember to configure Custom Modes in settings.json for Roo/Cline.',
42
+ ROO_WARNING_TITLE: 'Warning',
43
+ FAILED: 'Failed',
44
+ },
45
+ TOOLS: {
46
+ GEMINI: 'Gemini CLI',
47
+ ROO: 'Roo Code',
48
+ CLINE: 'Cline',
49
+ CURSOR: 'Cursor',
50
+ WINDSURF: 'Windsurf',
51
+ TRAE: 'Trae IDE',
52
+ KILO: 'Kilo Code',
53
+ COPILOT: 'GitHub Copilot',
54
+ WEB: 'OpenAI / Claude',
55
+ OPENCODE: 'OpenCode',
56
+ },
57
+ LANGUAGE_RULES: {
58
+ EN: 'Always reply in English unless told otherwise.',
59
+ PT_BR: 'Responda sempre em Português (Brasil), a menos que solicitado o contrário.',
60
+ ES: 'Responda siempre en Español, a menos que se solicite lo contrario.',
61
+ },
62
+ DASHBOARD: {
63
+ TITLE: '🚀 PROJECT:',
64
+ PHASE: '📅 PHASE:',
65
+ STATUS: '📡 STATUS:',
66
+ OVERALL: 'OVERALL STATUS',
67
+ COMPLETED: 'Completed',
68
+ PENDING: 'Pending',
69
+ RECENT: 'RECENT ACTIVITY',
70
+ NO_ACTIVITY: 'No recent activity recorded.',
71
+ ACTION: ' 👉 ACTION: ',
72
+ HINT: 'Use',
73
+ HINT_SUFFIX: 'to work.',
74
+ LOADING: 'Loading Dashboard...',
75
+ SUCCESS: 'Dashboard updated.',
76
+ ERROR: 'Error loading dashboard.'
77
+ }
78
+ };
79
+
80
+ const PT_BR = {
81
+ INTRO: {
82
+ TITLE: ' UNIVERSAL SPEC CLI ',
83
+ UPGRADE_TITLE: ' SDD TOOLKIT: MODO ATUALIZAÇÃO ',
84
+ },
85
+ GENERAL: {
86
+ CANCELLED: 'Operação cancelada.',
87
+ },
88
+ UPGRADE: {
89
+ NO_CONFIG: 'Nenhuma configuração existente detectada. Iniciando instalação padrão.',
90
+ NO_CONFIG_TITLE: 'Info',
91
+ DETECTED_TOOLS: (tools) => `Ferramentas detectadas: ${tools}`,
92
+ DETECTED_TITLE: 'Atualizando...',
93
+ SUCCESS: 'Agentes atualizados com sucesso! 🚀',
94
+ },
95
+ SCAFFOLD: {
96
+ LOADING: 'Verificando estrutura do workspace...',
97
+ SUCCESS: '✔ Estrutura de pastas (.sdd-toolkit/) criada.',
98
+ ALREADY_EXISTS: '✔ Estrutura de pastas (.sdd-toolkit/) verificada.',
99
+ ERROR: 'Falha ao verificar estrutura do workspace.',
100
+ },
101
+ SETUP: {
102
+ STACK_SELECT: 'Qual é o perfil de tecnologia (Stack)?',
103
+ GLOBAL_RULES: 'Deseja adicionar Regras Globais para TODOS os agentes?',
104
+ GLOBAL_RULES_HINT: 'Ex: Sempre responda em Português; Use Conventional Commits...',
105
+ TOOL_SELECT: 'Para quais ferramentas você deseja instalar os Agentes?',
106
+ TOOL_HINT: 'Espaço para selecionar, Enter para confirmar',
107
+ NO_TOOLS: 'Nenhuma ferramenta selecionada. Operação cancelada.',
108
+ SUCCESS: 'Instalação concluída com sucesso! 🚀',
109
+ },
110
+ INSTALL: {
111
+ LOADING: 'Carregando definições...',
112
+ NO_AGENTS: 'Nenhum agente válido encontrado.',
113
+ INSTALLING: (tools) => `Instalando agentes para: ${tools}...`,
114
+ FINISHED: 'Instalação finalizada!',
115
+ ROO_WARNING: 'Lembre-se de configurar os Custom Modes em settings.json para Roo/Cline.',
116
+ ROO_WARNING_TITLE: 'Aviso',
117
+ FAILED: 'Falhou',
118
+ },
119
+ TOOLS: {
120
+ GEMINI: 'Gemini CLI',
121
+ ROO: 'Roo Code',
122
+ CLINE: 'Cline',
123
+ CURSOR: 'Cursor',
124
+ WINDSURF: 'Windsurf',
125
+ TRAE: 'Trae IDE',
126
+ KILO: 'Kilo Code',
127
+ COPILOT: 'GitHub Copilot',
128
+ WEB: 'OpenAI / Claude',
129
+ OPENCODE: 'OpenCode',
130
+ },
131
+ LANGUAGE_RULES: {
132
+ EN: 'Always reply in English unless told otherwise.',
133
+ PT_BR: 'Responda sempre em Português (Brasil), a menos que solicitado o contrário.',
134
+ ES: 'Responda sempre en Español, a menos que se solicite lo contrario.',
135
+ },
136
+ DASHBOARD: {
137
+ TITLE: '🚀 PROJETO:',
138
+ PHASE: '📅 FASE:',
139
+ STATUS: '📡 STATUS:',
140
+ OVERALL: 'STATUS GERAL',
141
+ COMPLETED: 'Concluídas',
142
+ PENDING: 'Pendentes',
143
+ RECENT: 'ATIVIDADE RECENTE',
144
+ NO_ACTIVITY: 'Nenhuma atividade recente registrada.',
145
+ ACTION: ' 👉 AÇÃO: ',
146
+ HINT: 'Use',
147
+ HINT_SUFFIX: 'para trabalhar.',
148
+ LOADING: 'Carregando Dashboard...',
149
+ SUCCESS: 'Dashboard atualizado.',
150
+ ERROR: 'Erro ao carregar dashboard.'
151
+ }
152
+ };
153
+
154
+ const ES = {
155
+ INTRO: {
156
+ TITLE: ' UNIVERSAL SPEC CLI ',
157
+ UPGRADE_TITLE: ' SDD TOOLKIT: MODO ACTUALIZACIÓN ',
158
+ },
159
+ GENERAL: {
160
+ CANCELLED: 'Operación cancelada.',
161
+ },
162
+ UPGRADE: {
163
+ NO_CONFIG: 'No se detectó configuración existente. Iniciando instalación estándar.',
164
+ NO_CONFIG_TITLE: 'Info',
165
+ DETECTED_TOOLS: (tools) => `Herramientas detectadas: ${tools}`,
166
+ DETECTED_TITLE: 'Actualizando...',
167
+ SUCCESS: '¡Agentes actualizados con éxito! 🚀',
168
+ },
169
+ SCAFFOLD: {
170
+ LOADING: 'Verificando estructura del espacio de trabajo...',
171
+ SUCCESS: '✔ Estructura de carpetas (.sdd-toolkit/) creada.',
172
+ ALREADY_EXISTS: '✔ Estructura de carpetas (.sdd-toolkit/) verificada.',
173
+ ERROR: 'Fallo al verificar estructura del espacio de trabajo.',
174
+ },
175
+ SETUP: {
176
+ STACK_SELECT: '¿Cuál es su perfil tecnológico (Stack)?',
177
+ GLOBAL_RULES: '¿Desea agregar Reglas Globales para TODOS los agentes?',
178
+ GLOBAL_RULES_HINT: 'Ej: Siempre responda en Español; Use Conventional Commits...',
179
+ TOOL_SELECT: '¿Para qué herramientas desea instalar los Agentes?',
180
+ TOOL_HINT: 'Espacio para seleccionar, Enter para confirmar',
181
+ NO_TOOLS: 'Ninguna herramienta seleccionada. Operación cancelada.',
182
+ SUCCESS: '¡Instalación completada con éxito! 🚀',
183
+ },
184
+ INSTALL: {
185
+ LOADING: 'Cargando definiciones...',
186
+ NO_AGENTS: 'No se encontraron agentes válidos.',
187
+ INSTALLING: (tools) => `Instalando agentes para: ${tools}...`,
188
+ FINISHED: '¡Instalación finalizada!',
189
+ ROO_WARNING: 'Recuerde configurar los Modos Personalizados en settings.json para Roo/Cline.',
190
+ ROO_WARNING_TITLE: 'Aviso',
191
+ FAILED: 'Falló',
192
+ },
193
+ TOOLS: {
194
+ GEMINI: 'Gemini CLI',
195
+ ROO: 'Roo Code',
196
+ CLINE: 'Cline',
197
+ CURSOR: 'Cursor',
198
+ WINDSURF: 'Windsurf',
199
+ TRAE: 'Trae IDE',
200
+ KILO: 'Kilo Code',
201
+ COPILOT: 'GitHub Copilot',
202
+ WEB: 'OpenAI / Claude',
203
+ OPENCODE: 'OpenCode',
204
+ },
205
+ LANGUAGE_RULES: {
206
+ EN: 'Always reply in English unless told otherwise.',
207
+ PT_BR: 'Responda siempre em Português (Brasil), a menos que solicitado o contrário.',
208
+ ES: 'Responda siempre en Español, a menos que se solicite lo contrario.',
209
+ },
210
+ DASHBOARD: {
211
+ TITLE: '🚀 PROYECTO:',
212
+ PHASE: '📅 FASE:',
213
+ STATUS: '📡 ESTADO:',
214
+ OVERALL: 'ESTADO GENERAL',
215
+ COMPLETED: 'Completadas',
216
+ PENDING: 'Pendientes',
217
+ RECENT: 'ACTIVIDAD RECIENTE',
218
+ NO_ACTIVITY: 'No hay actividad reciente registrada.',
219
+ ACTION: ' 👉 ACCIÓN: ',
220
+ HINT: 'Use',
221
+ HINT_SUFFIX: 'para trabajar.',
222
+ LOADING: 'Cargando Dashboard...',
223
+ SUCCESS: 'Dashboard actualizado.',
224
+ ERROR: 'Error al cargar dashboard.'
225
+ }
226
+ };
227
+
228
+ const TRANSLATIONS = {
229
+ en: EN,
230
+ pt_br: PT_BR,
231
+ es: ES
232
+ };
233
+
234
+ module.exports = { TRANSLATIONS, MESSAGES: EN };
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Perfis de Stack Técnica
3
- * Define regras adicionais que serão injetadas nos agentes
2
+ * Technical Stack Profiles
3
+ * Defines additional rules to be injected into agents
4
4
  */
5
5
 
6
6
  const STACK_PROFILES = {
7
7
  // --- GENERIC ---
8
8
  'generic': {
9
- label: '🌐 Genérico / Nenhum',
9
+ label: '🌐 Generic / None',
10
10
  rules: []
11
11
  },
12
12
 
@@ -183,4 +183,4 @@ const STACK_PROFILES = {
183
183
  }
184
184
  };
185
185
 
186
- module.exports = { STACK_PROFILES };
186
+ module.exports = { STACK_PROFILES };