roadmap-kit 1.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/INSTALL.md +358 -0
- package/LICENSE +21 -0
- package/README.md +503 -0
- package/cli.js +548 -0
- package/dashboard/dist/assets/index-BzYzLB7u.css +1 -0
- package/dashboard/dist/assets/index-DIonhzlK.js +506 -0
- package/dashboard/dist/index.html +18 -0
- package/dashboard/dist/roadmap.json +268 -0
- package/dashboard/index.html +17 -0
- package/dashboard/package-lock.json +4172 -0
- package/dashboard/package.json +37 -0
- package/dashboard/postcss.config.js +6 -0
- package/dashboard/public/roadmap.json +268 -0
- package/dashboard/server.js +1366 -0
- package/dashboard/src/App.jsx +6979 -0
- package/dashboard/src/components/CircularProgress.jsx +55 -0
- package/dashboard/src/components/ProgressBar.jsx +33 -0
- package/dashboard/src/components/ProjectSettings.jsx +420 -0
- package/dashboard/src/components/SharedResources.jsx +239 -0
- package/dashboard/src/components/TaskList.jsx +273 -0
- package/dashboard/src/components/TechnicalDebt.jsx +170 -0
- package/dashboard/src/components/ui/accordion.jsx +46 -0
- package/dashboard/src/components/ui/badge.jsx +38 -0
- package/dashboard/src/components/ui/card.jsx +60 -0
- package/dashboard/src/components/ui/progress.jsx +22 -0
- package/dashboard/src/components/ui/tabs.jsx +47 -0
- package/dashboard/src/index.css +440 -0
- package/dashboard/src/lib/utils.js +6 -0
- package/dashboard/src/main.jsx +10 -0
- package/dashboard/tailwind.config.js +142 -0
- package/dashboard/vite.config.js +18 -0
- package/docker/Dockerfile +35 -0
- package/docker/docker-compose.yml +30 -0
- package/docker/entrypoint.sh +31 -0
- package/package.json +68 -0
- package/scanner.js +351 -0
- package/setup.sh +354 -0
- package/templates/clinerules.template +130 -0
- package/templates/roadmap.template.json +30 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export default function CircularProgress({ percentage = 0, size = 120, strokeWidth = 8 }) {
|
|
4
|
+
const radius = (size - strokeWidth) / 2;
|
|
5
|
+
const circumference = radius * 2 * Math.PI;
|
|
6
|
+
const offset = circumference - (percentage / 100) * circumference;
|
|
7
|
+
|
|
8
|
+
const gradientId = `progress-${Math.random().toString(36).substr(2, 9)}`;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<div className="relative" style={{ width: size, height: size }}>
|
|
12
|
+
<svg width={size} height={size} className="transform -rotate-90">
|
|
13
|
+
<defs>
|
|
14
|
+
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
|
|
15
|
+
<stop offset="0%" stopColor="#3b82f6" />
|
|
16
|
+
<stop offset="50%" stopColor="#06b6d4" />
|
|
17
|
+
<stop offset="100%" stopColor="#22d3ee" />
|
|
18
|
+
</linearGradient>
|
|
19
|
+
</defs>
|
|
20
|
+
|
|
21
|
+
{/* Background */}
|
|
22
|
+
<circle
|
|
23
|
+
cx={size / 2}
|
|
24
|
+
cy={size / 2}
|
|
25
|
+
r={radius}
|
|
26
|
+
fill="none"
|
|
27
|
+
stroke="rgba(255,255,255,0.05)"
|
|
28
|
+
strokeWidth={strokeWidth}
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
{/* Progress */}
|
|
32
|
+
<circle
|
|
33
|
+
cx={size / 2}
|
|
34
|
+
cy={size / 2}
|
|
35
|
+
r={radius}
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke={`url(#${gradientId})`}
|
|
38
|
+
strokeWidth={strokeWidth}
|
|
39
|
+
strokeLinecap="round"
|
|
40
|
+
strokeDasharray={circumference}
|
|
41
|
+
strokeDashoffset={offset}
|
|
42
|
+
className="transition-all duration-700 ease-out"
|
|
43
|
+
style={{
|
|
44
|
+
filter: 'drop-shadow(0 0 6px rgba(59, 130, 246, 0.5))'
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
</svg>
|
|
48
|
+
|
|
49
|
+
{/* Center text */}
|
|
50
|
+
<div className="absolute inset-0 flex items-center justify-center">
|
|
51
|
+
<span className="text-lg font-bold text-gradient-blue">{percentage}%</span>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ProgressBar Component
|
|
5
|
+
* Displays an animated progress bar with percentage
|
|
6
|
+
*/
|
|
7
|
+
export default function ProgressBar({ percentage = 0, label = '', color = 'green' }) {
|
|
8
|
+
const colorClasses = {
|
|
9
|
+
green: 'bg-status-completed',
|
|
10
|
+
yellow: 'bg-status-progress',
|
|
11
|
+
gray: 'bg-status-pending',
|
|
12
|
+
blue: 'bg-blue-500'
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const bgColor = colorClasses[color] || colorClasses.green;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="w-full">
|
|
19
|
+
{label && (
|
|
20
|
+
<div className="flex justify-between mb-1">
|
|
21
|
+
<span className="text-sm font-medium text-dark-text">{label}</span>
|
|
22
|
+
<span className="text-sm font-medium text-dark-text">{percentage}%</span>
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
<div className="w-full bg-dark-border rounded-full h-2.5 overflow-hidden">
|
|
26
|
+
<div
|
|
27
|
+
className={`h-2.5 rounded-full transition-all duration-500 ease-out ${bgColor}`}
|
|
28
|
+
style={{ width: `${percentage}%` }}
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Settings, Download, FileCode, Copy, Check, RefreshCw } from 'lucide-react';
|
|
3
|
+
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from './ui/card';
|
|
4
|
+
import { Badge } from './ui/badge';
|
|
5
|
+
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './ui/accordion';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ProjectSettings Component
|
|
9
|
+
* Manage project conventions and generate .clinerules file
|
|
10
|
+
*/
|
|
11
|
+
export default function ProjectSettings({ roadmap = {}, onReload }) {
|
|
12
|
+
const [copiedSection, setCopiedSection] = useState(null);
|
|
13
|
+
const [editMode, setEditMode] = useState(false);
|
|
14
|
+
const [conventions, setConventions] = useState(roadmap?.project_info?.conventions || {});
|
|
15
|
+
|
|
16
|
+
const copyToClipboard = (text, id) => {
|
|
17
|
+
navigator.clipboard.writeText(text);
|
|
18
|
+
setCopiedSection(id);
|
|
19
|
+
setTimeout(() => setCopiedSection(null), 2000);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Generate .clinerules content
|
|
23
|
+
const generateClinerules = () => {
|
|
24
|
+
const projectInfo = roadmap?.project_info || {};
|
|
25
|
+
const { ui_components = [], utilities = [], database_tables = [] } = projectInfo.shared_resources || {};
|
|
26
|
+
|
|
27
|
+
return `# Reglas del Proyecto: ${projectInfo.name || '[PROJECT_NAME]'}
|
|
28
|
+
|
|
29
|
+
## 🎯 Contexto General
|
|
30
|
+
${projectInfo.description || '[PROJECT_DESCRIPTION]'}
|
|
31
|
+
|
|
32
|
+
**Propósito:** ${projectInfo.purpose || '[PROJECT_PURPOSE]'}
|
|
33
|
+
|
|
34
|
+
## 📐 Arquitectura
|
|
35
|
+
${projectInfo.architecture || '[ARCHITECTURE_DESCRIPTION]'}
|
|
36
|
+
|
|
37
|
+
**Stack Tecnológico:**
|
|
38
|
+
${projectInfo.stack ? projectInfo.stack.map(tech => `- ${tech}`).join('\n') : '- [STACK_ITEMS]'}
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🛠️ Sistema de Gestión de Proyecto (OBLIGATORIO)
|
|
43
|
+
|
|
44
|
+
Este proyecto utiliza **ROADMAP-KIT** para gestionar el progreso y mantener la coherencia.
|
|
45
|
+
|
|
46
|
+
### 📋 Reglas de Operación:
|
|
47
|
+
|
|
48
|
+
1. **📖 Consulta el Roadmap SIEMPRE:**
|
|
49
|
+
- ANTES de empezar cualquier tarea, lee \`roadmap-kit/roadmap.json\`
|
|
50
|
+
- Verifica el contexto, las dependencias y los recursos compartidos
|
|
51
|
+
- Busca tu tarea específica por \`id\` y lee su \`description\`
|
|
52
|
+
|
|
53
|
+
2. **♻️ NO Duplicar - Reutilizar:**
|
|
54
|
+
- Consulta la sección \`shared_resources\` en el JSON
|
|
55
|
+
- Si una utilidad, componente o tabla DB ya existe, **DEBES reutilizarla**
|
|
56
|
+
- Añade el recurso reutilizado a \`reused_resources\` de tu tarea
|
|
57
|
+
- **NUNCA** crees componentes, funciones o tablas duplicadas
|
|
58
|
+
|
|
59
|
+
3. **📝 Actualización Post-Tarea:**
|
|
60
|
+
Al finalizar una tarea, actualiza el \`roadmap.json\` con:
|
|
61
|
+
- \`status\`: "completed" (o "in_progress" si no terminaste)
|
|
62
|
+
- \`ai_notes\`: Explica QUÉ decisiones tomaste y POR QUÉ
|
|
63
|
+
- \`affected_files\`: Lista TODOS los archivos que creaste o modificaste
|
|
64
|
+
- \`reused_resources\`: Lista los recursos compartidos que usaste
|
|
65
|
+
- \`technical_debt\`: Si dejaste algo pendiente, "sucio" o temporal, anótalo aquí con severidad (high/medium/low) y esfuerzo estimado
|
|
66
|
+
|
|
67
|
+
4. **🔖 Formato de Commit:**
|
|
68
|
+
Cada vez que termines una tarea, genera un commit con este formato EXACTO:
|
|
69
|
+
\`\`\`
|
|
70
|
+
[task:ID_DE_LA_TAREA] [status:completed] Breve descripción del cambio
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
Ejemplos:
|
|
74
|
+
\`\`\`
|
|
75
|
+
[task:auth-login] [status:completed] Implementa endpoint de login con JWT
|
|
76
|
+
[task:user-list] [status:in_progress] [debt:Falta paginación] Añade listado básico
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
5. **⚠️ Reportar Deuda Técnica:**
|
|
80
|
+
Si detectas algo que debe mejorarse pero no tienes tiempo ahora:
|
|
81
|
+
\`\`\`
|
|
82
|
+
[task:payment-api] [status:completed] [debt:Falta validación de tarjetas] [debt:Sin logs centralizados] Implementa endpoint de pagos
|
|
83
|
+
\`\`\`
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 📝 Convenciones de Código
|
|
88
|
+
|
|
89
|
+
### Nomenclatura
|
|
90
|
+
${conventions.naming ? Object.entries(conventions.naming).map(([key, value]) => `- **${key.charAt(0).toUpperCase() + key.slice(1)}**: ${value}`).join('\n') : `- **Variables y funciones**: camelCase
|
|
91
|
+
- **Componentes**: PascalCase
|
|
92
|
+
- **Archivos**: kebab-case
|
|
93
|
+
- **Constantes**: UPPER_SNAKE_CASE`}
|
|
94
|
+
|
|
95
|
+
### Estructura de Archivos
|
|
96
|
+
${conventions.file_structure || '[FILE_STRUCTURE_DESCRIPTION]'}
|
|
97
|
+
|
|
98
|
+
### Base de Datos
|
|
99
|
+
${conventions.database || '[DATABASE_CONVENTIONS]'}
|
|
100
|
+
|
|
101
|
+
### Estilos
|
|
102
|
+
${conventions.styling || '[STYLING_CONVENTIONS]'}
|
|
103
|
+
|
|
104
|
+
### Manejo de Errores
|
|
105
|
+
${conventions.error_handling || '[ERROR_HANDLING_CONVENTIONS]'}
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 🚫 Recursos Compartidos (NO DUPLICAR)
|
|
110
|
+
|
|
111
|
+
### Componentes UI Existentes
|
|
112
|
+
**ANTES de crear un nuevo componente UI, verifica si ya existe uno similar:**
|
|
113
|
+
|
|
114
|
+
${ui_components.length > 0 ? ui_components.map(comp => `- \`${comp.path}\` - ${comp.description}
|
|
115
|
+
- Uso: \`${comp.usage || 'N/A'}\``).join('\n\n') : '*(No hay componentes UI registrados aún)*'}
|
|
116
|
+
|
|
117
|
+
### Utilidades Existentes
|
|
118
|
+
**SIEMPRE importar estas utilidades. NO duplicar lógica:**
|
|
119
|
+
|
|
120
|
+
${utilities.length > 0 ? utilities.map(util => `- \`${util.path}\` - ${util.description}
|
|
121
|
+
- Exports: ${util.exports ? util.exports.map(e => `'${e}'`).join(', ') : 'N/A'}
|
|
122
|
+
- Uso: \`${util.usage || 'N/A'}\`${util.warning ? `\n - ⚠️ **IMPORTANTE**: ${util.warning}` : ''}`).join('\n\n') : '*(No hay utilidades registradas aún)*'}
|
|
123
|
+
|
|
124
|
+
### Base de Datos
|
|
125
|
+
**Tablas existentes:**
|
|
126
|
+
|
|
127
|
+
${database_tables.length > 0 ? database_tables.map(table => `- \`${table.name}\` (${table.fields.join(', ')})
|
|
128
|
+
- ${table.description}`).join('\n\n') : '*(No hay tablas registradas aún)*'}
|
|
129
|
+
|
|
130
|
+
**IMPORTANTE:** NO crear nuevas tablas sin consultar el roadmap y actualizar \`shared_resources\`.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 🔄 Flujo de Trabajo
|
|
135
|
+
|
|
136
|
+
1. **Inicio de Tarea:**
|
|
137
|
+
\`\`\`bash
|
|
138
|
+
# Lee el roadmap
|
|
139
|
+
cat roadmap-kit/roadmap.json
|
|
140
|
+
# Busca tu tarea por ID
|
|
141
|
+
\`\`\`
|
|
142
|
+
|
|
143
|
+
2. **Durante el Desarrollo:**
|
|
144
|
+
- Reutiliza componentes y utilidades existentes
|
|
145
|
+
- Sigue las convenciones de nomenclatura
|
|
146
|
+
- NO refactorices código que no está relacionado con tu tarea
|
|
147
|
+
|
|
148
|
+
3. **Al Finalizar:**
|
|
149
|
+
\`\`\`bash
|
|
150
|
+
# Actualiza el roadmap.json (campos: status, ai_notes, affected_files, etc.)
|
|
151
|
+
# Haz commit con el formato correcto
|
|
152
|
+
git add .
|
|
153
|
+
git commit -m "[task:tu-task-id] [status:completed] Descripción del cambio"
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
4. **Sincronización:**
|
|
157
|
+
\`\`\`bash
|
|
158
|
+
# El scanner automático leerá tu commit y actualizará métricas
|
|
159
|
+
npm run roadmap:scan
|
|
160
|
+
\`\`\`
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 📊 Visualización del Progreso
|
|
165
|
+
|
|
166
|
+
Para ver el estado del proyecto:
|
|
167
|
+
|
|
168
|
+
\`\`\`bash
|
|
169
|
+
npm run roadmap # Abre el dashboard visual
|
|
170
|
+
npm run roadmap:scan # Actualiza desde Git
|
|
171
|
+
\`\`\`
|
|
172
|
+
|
|
173
|
+
O con Docker:
|
|
174
|
+
\`\`\`bash
|
|
175
|
+
docker-compose up roadmap-dashboard
|
|
176
|
+
\`\`\`
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## ✅ Checklist Antes de Cada Commit
|
|
181
|
+
|
|
182
|
+
- [ ] ¿Leí la descripción de mi tarea en roadmap.json?
|
|
183
|
+
- [ ] ¿Verifiqué que no estoy duplicando componentes/utilidades existentes?
|
|
184
|
+
- [ ] ¿Seguí las convenciones de nomenclatura del proyecto?
|
|
185
|
+
- [ ] ¿Actualicé el roadmap.json con mis cambios?
|
|
186
|
+
- [ ] ¿Añadí ai_notes explicando mis decisiones?
|
|
187
|
+
- [ ] ¿Listé todos los affected_files?
|
|
188
|
+
- [ ] ¿Reporté la technical_debt si existe?
|
|
189
|
+
- [ ] ¿Usé el formato correcto de commit \`[task:id] [status:...]\`?
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
**🗺️ ROADMAP-KIT** - Because AI needs context too.
|
|
194
|
+
|
|
195
|
+
Última sincronización: ${projectInfo.last_sync ? new Date(projectInfo.last_sync).toLocaleString() : 'Nunca'}
|
|
196
|
+
`;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const downloadClinerules = () => {
|
|
200
|
+
const content = generateClinerules();
|
|
201
|
+
const blob = new Blob([content], { type: 'text/markdown' });
|
|
202
|
+
const url = URL.createObjectURL(blob);
|
|
203
|
+
const a = document.createElement('a');
|
|
204
|
+
a.href = url;
|
|
205
|
+
a.download = '.clinerules';
|
|
206
|
+
document.body.appendChild(a);
|
|
207
|
+
a.click();
|
|
208
|
+
document.body.removeChild(a);
|
|
209
|
+
URL.revokeObjectURL(url);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const projectInfo = roadmap?.project_info || {};
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<div className="space-y-6">
|
|
216
|
+
{/* Header */}
|
|
217
|
+
<Card className="bg-gradient-to-br from-purple-900/20 to-purple-800/10 border-purple-700/50">
|
|
218
|
+
<CardHeader>
|
|
219
|
+
<div className="flex items-center justify-between">
|
|
220
|
+
<div>
|
|
221
|
+
<CardTitle className="flex items-center gap-2 text-purple-400">
|
|
222
|
+
<Settings className="w-6 h-6" />
|
|
223
|
+
Configuración del Proyecto
|
|
224
|
+
</CardTitle>
|
|
225
|
+
<CardDescription className="mt-2">
|
|
226
|
+
Gestiona las convenciones y genera el archivo .clinerules para Claude/Cursor/Cline
|
|
227
|
+
</CardDescription>
|
|
228
|
+
</div>
|
|
229
|
+
<button
|
|
230
|
+
onClick={onReload}
|
|
231
|
+
className="p-3 hover:bg-purple-500/10 rounded-lg transition-all hover:scale-105"
|
|
232
|
+
title="Recargar"
|
|
233
|
+
>
|
|
234
|
+
<RefreshCw className="w-5 h-5 text-purple-400" />
|
|
235
|
+
</button>
|
|
236
|
+
</div>
|
|
237
|
+
</CardHeader>
|
|
238
|
+
</Card>
|
|
239
|
+
|
|
240
|
+
{/* Quick Info */}
|
|
241
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
242
|
+
<Card className="bg-slate-900/50 border-slate-700/50">
|
|
243
|
+
<CardContent className="p-6">
|
|
244
|
+
<h3 className="text-sm text-slate-400 mb-1">Nombre del Proyecto</h3>
|
|
245
|
+
<p className="text-lg font-semibold text-slate-100">{projectInfo.name || 'Sin nombre'}</p>
|
|
246
|
+
</CardContent>
|
|
247
|
+
</Card>
|
|
248
|
+
|
|
249
|
+
<Card className="bg-slate-900/50 border-slate-700/50">
|
|
250
|
+
<CardContent className="p-6">
|
|
251
|
+
<h3 className="text-sm text-slate-400 mb-1">Versión</h3>
|
|
252
|
+
<p className="text-lg font-semibold text-slate-100">{projectInfo.version || '1.0.0'}</p>
|
|
253
|
+
</CardContent>
|
|
254
|
+
</Card>
|
|
255
|
+
|
|
256
|
+
<Card className="bg-slate-900/50 border-slate-700/50">
|
|
257
|
+
<CardContent className="p-6">
|
|
258
|
+
<h3 className="text-sm text-slate-400 mb-1">Stack</h3>
|
|
259
|
+
<p className="text-lg font-semibold text-slate-100">
|
|
260
|
+
{projectInfo.stack ? projectInfo.stack.length : 0} tecnologías
|
|
261
|
+
</p>
|
|
262
|
+
</CardContent>
|
|
263
|
+
</Card>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
{/* Generate .clinerules */}
|
|
267
|
+
<Card className="bg-slate-900/50 border-slate-700/50">
|
|
268
|
+
<CardHeader>
|
|
269
|
+
<CardTitle className="flex items-center gap-2">
|
|
270
|
+
<FileCode className="w-5 h-5 text-emerald-400" />
|
|
271
|
+
Generar .clinerules
|
|
272
|
+
</CardTitle>
|
|
273
|
+
<CardDescription>
|
|
274
|
+
Archivo de configuración para que Claude/Cursor/Cline siga las reglas del proyecto
|
|
275
|
+
</CardDescription>
|
|
276
|
+
</CardHeader>
|
|
277
|
+
<CardContent className="space-y-4">
|
|
278
|
+
<div className="flex gap-3">
|
|
279
|
+
<button
|
|
280
|
+
onClick={downloadClinerules}
|
|
281
|
+
className="flex items-center gap-2 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors"
|
|
282
|
+
>
|
|
283
|
+
<Download className="w-4 h-4" />
|
|
284
|
+
Descargar .clinerules
|
|
285
|
+
</button>
|
|
286
|
+
|
|
287
|
+
<button
|
|
288
|
+
onClick={() => copyToClipboard(generateClinerules(), 'clinerules')}
|
|
289
|
+
className="flex items-center gap-2 px-4 py-2 bg-slate-700 hover:bg-slate-600 text-white rounded-lg transition-colors"
|
|
290
|
+
>
|
|
291
|
+
{copiedSection === 'clinerules' ? (
|
|
292
|
+
<>
|
|
293
|
+
<Check className="w-4 h-4" />
|
|
294
|
+
Copiado!
|
|
295
|
+
</>
|
|
296
|
+
) : (
|
|
297
|
+
<>
|
|
298
|
+
<Copy className="w-4 h-4" />
|
|
299
|
+
Copiar al Portapapeles
|
|
300
|
+
</>
|
|
301
|
+
)}
|
|
302
|
+
</button>
|
|
303
|
+
</div>
|
|
304
|
+
|
|
305
|
+
<div className="bg-slate-950/50 rounded-lg p-4 border border-slate-700/50 max-h-96 overflow-y-auto scrollbar-dark">
|
|
306
|
+
<pre className="text-xs text-slate-300 whitespace-pre-wrap font-mono">
|
|
307
|
+
{generateClinerules()}
|
|
308
|
+
</pre>
|
|
309
|
+
</div>
|
|
310
|
+
</CardContent>
|
|
311
|
+
</Card>
|
|
312
|
+
|
|
313
|
+
{/* Conventions */}
|
|
314
|
+
<Card className="bg-slate-900/50 border-slate-700/50">
|
|
315
|
+
<CardHeader>
|
|
316
|
+
<CardTitle>Convenciones del Proyecto</CardTitle>
|
|
317
|
+
<CardDescription>
|
|
318
|
+
Define las reglas de nomenclatura y estructura que la IA debe seguir
|
|
319
|
+
</CardDescription>
|
|
320
|
+
</CardHeader>
|
|
321
|
+
<CardContent>
|
|
322
|
+
<Accordion type="multiple" className="space-y-2">
|
|
323
|
+
{/* Naming */}
|
|
324
|
+
<Card className="bg-slate-800/30 border-slate-700/50">
|
|
325
|
+
<AccordionItem value="naming" className="border-none">
|
|
326
|
+
<AccordionTrigger className="hover:no-underline px-4">
|
|
327
|
+
<div className="flex items-center gap-2">
|
|
328
|
+
<FileCode className="w-4 h-4 text-blue-400" />
|
|
329
|
+
<span>Nomenclatura</span>
|
|
330
|
+
<Badge variant="secondary">{Object.keys(conventions.naming || {}).length} reglas</Badge>
|
|
331
|
+
</div>
|
|
332
|
+
</AccordionTrigger>
|
|
333
|
+
<AccordionContent>
|
|
334
|
+
<div className="px-4 pb-4 space-y-2">
|
|
335
|
+
{conventions.naming && Object.entries(conventions.naming).map(([key, value]) => (
|
|
336
|
+
<div key={key} className="flex items-center justify-between bg-slate-900/50 p-3 rounded-lg">
|
|
337
|
+
<span className="text-sm text-slate-400">{key}:</span>
|
|
338
|
+
<code className="text-sm text-emerald-400">{value}</code>
|
|
339
|
+
</div>
|
|
340
|
+
))}
|
|
341
|
+
</div>
|
|
342
|
+
</AccordionContent>
|
|
343
|
+
</AccordionItem>
|
|
344
|
+
</Card>
|
|
345
|
+
|
|
346
|
+
{/* Architecture */}
|
|
347
|
+
<Card className="bg-slate-800/30 border-slate-700/50">
|
|
348
|
+
<AccordionItem value="architecture" className="border-none">
|
|
349
|
+
<AccordionTrigger className="hover:no-underline px-4">
|
|
350
|
+
<div className="flex items-center gap-2">
|
|
351
|
+
<FileCode className="w-4 h-4 text-purple-400" />
|
|
352
|
+
<span>Arquitectura</span>
|
|
353
|
+
</div>
|
|
354
|
+
</AccordionTrigger>
|
|
355
|
+
<AccordionContent>
|
|
356
|
+
<div className="px-4 pb-4">
|
|
357
|
+
<div className="bg-slate-900/50 p-4 rounded-lg">
|
|
358
|
+
<p className="text-sm text-slate-300">{projectInfo.architecture || 'No definida'}</p>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
</AccordionContent>
|
|
362
|
+
</AccordionItem>
|
|
363
|
+
</Card>
|
|
364
|
+
|
|
365
|
+
{/* File Structure */}
|
|
366
|
+
<Card className="bg-slate-800/30 border-slate-700/50">
|
|
367
|
+
<AccordionItem value="structure" className="border-none">
|
|
368
|
+
<AccordionTrigger className="hover:no-underline px-4">
|
|
369
|
+
<div className="flex items-center gap-2">
|
|
370
|
+
<FileCode className="w-4 h-4 text-amber-400" />
|
|
371
|
+
<span>Estructura de Archivos</span>
|
|
372
|
+
</div>
|
|
373
|
+
</AccordionTrigger>
|
|
374
|
+
<AccordionContent>
|
|
375
|
+
<div className="px-4 pb-4">
|
|
376
|
+
<div className="bg-slate-900/50 p-4 rounded-lg">
|
|
377
|
+
<p className="text-sm text-slate-300">{conventions.file_structure || 'No definida'}</p>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
</AccordionContent>
|
|
381
|
+
</AccordionItem>
|
|
382
|
+
</Card>
|
|
383
|
+
|
|
384
|
+
{/* Database */}
|
|
385
|
+
<Card className="bg-slate-800/30 border-slate-700/50">
|
|
386
|
+
<AccordionItem value="database" className="border-none">
|
|
387
|
+
<AccordionTrigger className="hover:no-underline px-4">
|
|
388
|
+
<div className="flex items-center gap-2">
|
|
389
|
+
<FileCode className="w-4 h-4 text-green-400" />
|
|
390
|
+
<span>Base de Datos</span>
|
|
391
|
+
</div>
|
|
392
|
+
</AccordionTrigger>
|
|
393
|
+
<AccordionContent>
|
|
394
|
+
<div className="px-4 pb-4">
|
|
395
|
+
<div className="bg-slate-900/50 p-4 rounded-lg">
|
|
396
|
+
<p className="text-sm text-slate-300">{conventions.database || 'No definida'}</p>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
</AccordionContent>
|
|
400
|
+
</AccordionItem>
|
|
401
|
+
</Card>
|
|
402
|
+
</Accordion>
|
|
403
|
+
</CardContent>
|
|
404
|
+
</Card>
|
|
405
|
+
|
|
406
|
+
{/* Instructions */}
|
|
407
|
+
<Card className="bg-blue-900/10 border-blue-700/50">
|
|
408
|
+
<CardContent className="p-6">
|
|
409
|
+
<h3 className="text-sm font-semibold text-blue-400 mb-3">📖 Instrucciones de Instalación</h3>
|
|
410
|
+
<div className="space-y-2 text-sm text-slate-300">
|
|
411
|
+
<p>1. Descarga o copia el contenido del archivo .clinerules</p>
|
|
412
|
+
<p>2. Colócalo en la raíz de tu proyecto como <code className="text-emerald-400">.clinerules</code></p>
|
|
413
|
+
<p>3. Si usas Cursor, renómbralo a <code className="text-emerald-400">.cursorrules</code></p>
|
|
414
|
+
<p>4. Claude/Cursor/Cline leerá automáticamente estas reglas antes de generar código</p>
|
|
415
|
+
</div>
|
|
416
|
+
</CardContent>
|
|
417
|
+
</Card>
|
|
418
|
+
</div>
|
|
419
|
+
);
|
|
420
|
+
}
|