specleap-framework 2.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/.agents/backend.md +419 -0
- package/.agents/frontend.md +577 -0
- package/.agents/producto.md +516 -0
- package/.commands/adoptar.md +323 -0
- package/.commands/ayuda.md +142 -0
- package/.commands/crear-tickets.md +55 -0
- package/.commands/documentar.md +285 -0
- package/.commands/explicar.md +234 -0
- package/.commands/implementar.md +383 -0
- package/.commands/inicio.md +824 -0
- package/.commands/nuevo/README.md +292 -0
- package/.commands/nuevo/questions-base.yaml +320 -0
- package/.commands/nuevo/responses-example.yaml +53 -0
- package/.commands/planificar.md +253 -0
- package/.commands/refinar.md +306 -0
- package/LICENSE +21 -0
- package/README.md +603 -0
- package/SETUP.md +351 -0
- package/install.sh +152 -0
- package/package.json +60 -0
- package/proyectos/_template/.gitkeep +1 -0
- package/proyectos/_template/ANEXOS.md +21 -0
- package/proyectos/_template/CONTRATO.md +26 -0
- package/proyectos/_template/context/.gitkeep +1 -0
- package/rules/development-rules.md +113 -0
- package/rules/environment-protection.md +97 -0
- package/rules/git-workflow.md +142 -0
- package/rules/session-protocol.md +121 -0
- package/scripts/README.md +129 -0
- package/scripts/analyze-project.sh +826 -0
- package/scripts/create-asana-tasks.sh +133 -0
- package/scripts/detect-project-type.sh +141 -0
- package/scripts/estimate-effort.sh +290 -0
- package/scripts/generate-asana-structure.sh +262 -0
- package/scripts/generate-contract.sh +360 -0
- package/scripts/generate-contrato.sh +555 -0
- package/scripts/install-git-hooks.sh +141 -0
- package/scripts/install-skills.sh +130 -0
- package/scripts/lib/asana-utils.sh +191 -0
- package/scripts/lib/jira-project-utils.sh +222 -0
- package/scripts/lib/questions.json +831 -0
- package/scripts/lib/render-contrato.py +195 -0
- package/scripts/lib/validate.sh +325 -0
- package/scripts/parse-contrato.sh +190 -0
- package/scripts/setup-mcp.sh +654 -0
- package/scripts/test-cuestionario.sh +428 -0
- package/setup.sh +458 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecLeap — Setup Completo Automatizado
|
|
4
|
+
# Verificación inteligente: solo instala lo que falta
|
|
5
|
+
|
|
6
|
+
set -e # Exit on error
|
|
7
|
+
|
|
8
|
+
# Colores para output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
CYAN='\033[0;36m'
|
|
14
|
+
NC='\033[0m' # No Color
|
|
15
|
+
|
|
16
|
+
echo -e "${BLUE}"
|
|
17
|
+
echo "╔════════════════════════════════════════════╗"
|
|
18
|
+
echo "║ SpecLeap — Setup Automatizado ║"
|
|
19
|
+
echo "║ Verificación Inteligente ║"
|
|
20
|
+
echo "╔════════════════════════════════════════════╗"
|
|
21
|
+
echo -e "${NC}"
|
|
22
|
+
echo ""
|
|
23
|
+
|
|
24
|
+
# ============================================
|
|
25
|
+
# VERIFICACIONES PREVIAS
|
|
26
|
+
# ============================================
|
|
27
|
+
|
|
28
|
+
echo -e "${CYAN}🔍 Verificando sistema...${NC}"
|
|
29
|
+
echo ""
|
|
30
|
+
|
|
31
|
+
# Verificar Node.js
|
|
32
|
+
if ! command -v node &> /dev/null; then
|
|
33
|
+
echo -e "${RED}❌ Node.js no está instalado${NC}"
|
|
34
|
+
echo "Instala Node.js desde: https://nodejs.org"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
echo -e "${GREEN}✅ Node.js:${NC} $(node --version)"
|
|
38
|
+
|
|
39
|
+
# Verificar npm
|
|
40
|
+
if ! command -v npm &> /dev/null; then
|
|
41
|
+
echo -e "${RED}❌ npm no está instalado${NC}"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
echo -e "${GREEN}✅ npm:${NC} $(npm --version)"
|
|
45
|
+
|
|
46
|
+
# Verificar Python 3 (necesario para manipular JSON)
|
|
47
|
+
if ! command -v python3 &> /dev/null; then
|
|
48
|
+
echo -e "${RED}❌ Python 3 no está instalado (necesario para configurar JSON)${NC}"
|
|
49
|
+
echo "Instala Python 3:"
|
|
50
|
+
echo " macOS: brew install python3"
|
|
51
|
+
echo " Ubuntu: sudo apt install python3"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
echo -e "${GREEN}✅ Python 3:${NC} $(python3 --version)"
|
|
55
|
+
|
|
56
|
+
# Verificar npx skills
|
|
57
|
+
if ! command -v npx &> /dev/null; then
|
|
58
|
+
echo -e "${RED}❌ npx no está disponible${NC}"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
echo -e "${GREEN}✅ npx:${NC} disponible"
|
|
62
|
+
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
# ============================================
|
|
66
|
+
# DETECTAR IDE
|
|
67
|
+
# ============================================
|
|
68
|
+
|
|
69
|
+
IDE=""
|
|
70
|
+
CONFIG_PATH=""
|
|
71
|
+
|
|
72
|
+
echo -e "${CYAN}🔍 Detectando IDE...${NC}"
|
|
73
|
+
|
|
74
|
+
if command -v code &> /dev/null; then
|
|
75
|
+
IDE="vscode"
|
|
76
|
+
CONFIG_PATH=~/.vscode/extensions
|
|
77
|
+
echo -e "${GREEN}✅ IDE detectado: VSCode${NC}"
|
|
78
|
+
elif [ -d ~/.cursor ]; then
|
|
79
|
+
IDE="cursor"
|
|
80
|
+
CONFIG_PATH=~/.cursor/config.json
|
|
81
|
+
echo -e "${GREEN}✅ IDE detectado: Cursor${NC}"
|
|
82
|
+
elif [ -d ~/.continue ]; then
|
|
83
|
+
IDE="continue"
|
|
84
|
+
CONFIG_PATH=.continue/config.json
|
|
85
|
+
echo -e "${GREEN}✅ IDE detectado: Continue (VSCode)${NC}"
|
|
86
|
+
else
|
|
87
|
+
echo -e "${RED}❌ No se detectó IDE compatible${NC}"
|
|
88
|
+
echo "Compatible con: VSCode, Cursor, Continue"
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
# ============================================
|
|
95
|
+
# VERIFICAR QUÉ YA ESTÁ INSTALADO
|
|
96
|
+
# ============================================
|
|
97
|
+
|
|
98
|
+
echo -e "${CYAN}📋 Verificando instalaciones existentes...${NC}"
|
|
99
|
+
echo ""
|
|
100
|
+
|
|
101
|
+
# Verificar Agent Skills
|
|
102
|
+
SKILLS_INSTALLED=false
|
|
103
|
+
if [ -d ~/.skills ]; then
|
|
104
|
+
SKILLS_COUNT=$(find ~/.skills -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
|
|
105
|
+
if [ "$SKILLS_COUNT" -gt 0 ]; then
|
|
106
|
+
echo -e "${GREEN}✅ Agent Skills detectadas: $SKILLS_COUNT instaladas${NC}"
|
|
107
|
+
SKILLS_INSTALLED=true
|
|
108
|
+
else
|
|
109
|
+
echo -e "${YELLOW}⚠️ Directorio ~/.skills existe pero está vacío${NC}"
|
|
110
|
+
fi
|
|
111
|
+
else
|
|
112
|
+
echo -e "${YELLOW}⚠️ Agent Skills: No instaladas${NC}"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Verificar CodeRabbit config
|
|
116
|
+
CODERABBIT_INSTALLED=false
|
|
117
|
+
if [ -f .coderabbit.yaml ]; then
|
|
118
|
+
echo -e "${GREEN}✅ CodeRabbit config: .coderabbit.yaml encontrado${NC}"
|
|
119
|
+
CODERABBIT_INSTALLED=true
|
|
120
|
+
else
|
|
121
|
+
echo -e "${YELLOW}⚠️ CodeRabbit config: No encontrado${NC}"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Verificar Asana en config
|
|
125
|
+
JIRA_INSTALLED=false
|
|
126
|
+
if [ -f "$CONFIG_PATH" ]; then
|
|
127
|
+
if grep -q "jira" "$CONFIG_PATH" 2>/dev/null; then
|
|
128
|
+
echo -e "${GREEN}✅ Asana: Configurado en $IDE${NC}"
|
|
129
|
+
JIRA_INSTALLED=true
|
|
130
|
+
else
|
|
131
|
+
echo -e "${YELLOW}⚠️ Asana: No configurado${NC}"
|
|
132
|
+
fi
|
|
133
|
+
else
|
|
134
|
+
echo -e "${YELLOW}⚠️ Asana: Archivo de config no existe${NC}"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Verificar Context7 MCP
|
|
138
|
+
CONTEXT7_INSTALLED=false
|
|
139
|
+
if [ -f "$CONFIG_PATH" ]; then
|
|
140
|
+
if grep -q "context7" "$CONFIG_PATH" 2>/dev/null; then
|
|
141
|
+
echo -e "${GREEN}✅ Context7 MCP: Configurado${NC}"
|
|
142
|
+
CONTEXT7_INSTALLED=true
|
|
143
|
+
fi
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
echo ""
|
|
147
|
+
|
|
148
|
+
# ============================================
|
|
149
|
+
# RESUMEN PRE-INSTALACIÓN
|
|
150
|
+
# ============================================
|
|
151
|
+
|
|
152
|
+
NEEDS_INSTALL=false
|
|
153
|
+
|
|
154
|
+
if [ "$SKILLS_INSTALLED" = false ] || [ "$CODERABBIT_INSTALLED" = false ] || [ "$JIRA_INSTALLED" = false ]; then
|
|
155
|
+
NEEDS_INSTALL=true
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
if [ "$NEEDS_INSTALL" = false ]; then
|
|
159
|
+
echo -e "${GREEN}"
|
|
160
|
+
echo "╔════════════════════════════════════════════╗"
|
|
161
|
+
echo "║ ✅ TODO YA ESTÁ INSTALADO ║"
|
|
162
|
+
echo "╔════════════════════════════════════════════╗"
|
|
163
|
+
echo -e "${NC}"
|
|
164
|
+
echo ""
|
|
165
|
+
echo "No hay nada que instalar. Sistema completo."
|
|
166
|
+
echo ""
|
|
167
|
+
echo "Verifica con: /refinar SCRUM-1"
|
|
168
|
+
echo ""
|
|
169
|
+
exit 0
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
echo -e "${BLUE}📦 Componentes a instalar:${NC}"
|
|
173
|
+
echo ""
|
|
174
|
+
if [ "$SKILLS_INSTALLED" = false ]; then
|
|
175
|
+
echo " 🔲 Agent Skills TIER 1 (20 skills)"
|
|
176
|
+
fi
|
|
177
|
+
if [ "$CODERABBIT_INSTALLED" = false ]; then
|
|
178
|
+
echo " 🔲 CodeRabbit config (.coderabbit.yaml)"
|
|
179
|
+
fi
|
|
180
|
+
if [ "$JIRA_INSTALLED" = false ]; then
|
|
181
|
+
echo " 🔲 Asana"
|
|
182
|
+
fi
|
|
183
|
+
if [ "$CONTEXT7_INSTALLED" = false ]; then
|
|
184
|
+
echo " 🔲 Context7 MCP (opcional)"
|
|
185
|
+
fi
|
|
186
|
+
echo ""
|
|
187
|
+
|
|
188
|
+
read -p "¿Continuar con la instalación? (s/n): " CONTINUE_INSTALL
|
|
189
|
+
if [[ ! "$CONTINUE_INSTALL" =~ ^[Ss]$ ]]; then
|
|
190
|
+
echo "Instalación cancelada."
|
|
191
|
+
exit 0
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
echo ""
|
|
195
|
+
|
|
196
|
+
# ============================================
|
|
197
|
+
# PASO 1: Agent Skills TIER 1
|
|
198
|
+
# ============================================
|
|
199
|
+
|
|
200
|
+
if [ "$SKILLS_INSTALLED" = false ]; then
|
|
201
|
+
echo -e "${BLUE}📚 Instalando Agent Skills TIER 1 (OBLIGATORIO)${NC}"
|
|
202
|
+
echo ""
|
|
203
|
+
echo "⚠️ Skills TIER 1 son OBLIGATORIAS para mantener calidad del código"
|
|
204
|
+
echo ""
|
|
205
|
+
echo "Tiempo estimado: ~2-3 minutos"
|
|
206
|
+
echo ""
|
|
207
|
+
|
|
208
|
+
# Lista de skills a instalar (formato: "repo:path:name")
|
|
209
|
+
declare -a SKILLS=(
|
|
210
|
+
# Consistencia & Calidad (5) - obra/superpowers
|
|
211
|
+
"obra/superpowers:skills/verification-before-completion:verification-before-completion"
|
|
212
|
+
"obra/superpowers:skills/systematic-debugging:systematic-debugging"
|
|
213
|
+
"obra/superpowers:skills/test-driven-development:test-driven-development"
|
|
214
|
+
"obra/superpowers:skills/requesting-code-review:requesting-code-review"
|
|
215
|
+
"obra/superpowers:skills/receiving-code-review:receiving-code-review"
|
|
216
|
+
|
|
217
|
+
# Backend & Full-Stack (8) - jeffallan/claude-skills
|
|
218
|
+
"jeffallan/claude-skills:skills/laravel-specialist:laravel-specialist"
|
|
219
|
+
"jeffallan/claude-skills:skills/api-designer:api-designer"
|
|
220
|
+
"jeffallan/claude-skills:skills/database-optimizer:database-optimizer"
|
|
221
|
+
"jeffallan/claude-skills:skills/code-reviewer:code-reviewer"
|
|
222
|
+
"jeffallan/claude-skills:skills/debugging-wizard:debugging-wizard"
|
|
223
|
+
"jeffallan/claude-skills:skills/python-pro:python-pro"
|
|
224
|
+
"jeffallan/claude-skills:skills/react-expert:react-expert"
|
|
225
|
+
"jeffallan/claude-skills:skills/typescript-pro:typescript-pro"
|
|
226
|
+
|
|
227
|
+
# Diseño & Frontend (4) - anthropics/skills
|
|
228
|
+
"anthropics/skills:skills/frontend-design:frontend-design"
|
|
229
|
+
"anthropics/skills:skills/skill-creator:skill-creator"
|
|
230
|
+
"anthropics/skills:skills/canvas-design:canvas-design"
|
|
231
|
+
"anthropics/skills:skills/algorithmic-art:algorithmic-art"
|
|
232
|
+
|
|
233
|
+
# DevOps & Arquitectura (3) - jeffallan/claude-skills
|
|
234
|
+
"jeffallan/claude-skills:skills/devops-engineer:devops-engineer"
|
|
235
|
+
"jeffallan/claude-skills:skills/cloud-architect:cloud-architect"
|
|
236
|
+
"jeffallan/claude-skills:skills/architecture-designer:architecture-designer"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
TOTAL_SKILLS=${#SKILLS[@]}
|
|
240
|
+
INSTALLED_COUNT=0
|
|
241
|
+
FAILED_COUNT=0
|
|
242
|
+
SKIPPED_COUNT=0
|
|
243
|
+
|
|
244
|
+
SKILLS_DIR="${HOME}/.skills"
|
|
245
|
+
TMP_DIR="/tmp/specleap-skills-$$"
|
|
246
|
+
|
|
247
|
+
mkdir -p "${SKILLS_DIR}"
|
|
248
|
+
mkdir -p "${TMP_DIR}"
|
|
249
|
+
|
|
250
|
+
echo -e "${CYAN}📦 Instalando skills desde GitHub...${NC}"
|
|
251
|
+
echo ""
|
|
252
|
+
|
|
253
|
+
for i in "${!SKILLS[@]}"; do
|
|
254
|
+
IFS=':' read -r repo path name <<< "${SKILLS[$i]}"
|
|
255
|
+
skill_num=$((i + 1))
|
|
256
|
+
|
|
257
|
+
echo -ne " [$skill_num/$TOTAL_SKILLS] $name... "
|
|
258
|
+
|
|
259
|
+
# Verificar si ya está instalada
|
|
260
|
+
if [ -d "${SKILLS_DIR}/${name}" ]; then
|
|
261
|
+
echo -e "${YELLOW}⚠️ (ya instalada)${NC}"
|
|
262
|
+
((SKIPPED_COUNT++))
|
|
263
|
+
continue
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
# Clonar repo si no existe
|
|
267
|
+
repo_dir="${TMP_DIR}/$(echo $repo | tr '/' '_')"
|
|
268
|
+
if [ ! -d "${repo_dir}" ]; then
|
|
269
|
+
git clone "https://github.com/${repo}.git" "${repo_dir}" &>/dev/null
|
|
270
|
+
if [ $? -ne 0 ]; then
|
|
271
|
+
echo -e "${RED}❌ (repo no accesible)${NC}"
|
|
272
|
+
((FAILED_COUNT++))
|
|
273
|
+
continue
|
|
274
|
+
fi
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# Copiar skill
|
|
278
|
+
if [ -f "${repo_dir}/${path}/SKILL.md" ]; then
|
|
279
|
+
cp -r "${repo_dir}/${path}" "${SKILLS_DIR}/${name}"
|
|
280
|
+
echo -e "${GREEN}✅${NC}"
|
|
281
|
+
((INSTALLED_COUNT++))
|
|
282
|
+
else
|
|
283
|
+
echo -e "${RED}❌ (SKILL.md no encontrado)${NC}"
|
|
284
|
+
((FAILED_COUNT++))
|
|
285
|
+
fi
|
|
286
|
+
done
|
|
287
|
+
|
|
288
|
+
# Cleanup
|
|
289
|
+
rm -rf "${TMP_DIR}"
|
|
290
|
+
|
|
291
|
+
echo ""
|
|
292
|
+
echo -e "${GREEN}✅ Skills instaladas exitosamente: $INSTALLED_COUNT${NC}"
|
|
293
|
+
if [ $SKIPPED_COUNT -gt 0 ]; then
|
|
294
|
+
echo -e "${YELLOW}⚠️ Skills ya instaladas: $SKIPPED_COUNT${NC}"
|
|
295
|
+
fi
|
|
296
|
+
if [ $FAILED_COUNT -gt 0 ]; then
|
|
297
|
+
echo -e "${RED}❌ Skills fallidas o no encontradas: $FAILED_COUNT${NC}"
|
|
298
|
+
fi
|
|
299
|
+
echo ""
|
|
300
|
+
else
|
|
301
|
+
echo -e "${GREEN}✅ Agent Skills ya instaladas — Omitiendo${NC}"
|
|
302
|
+
echo ""
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
# ============================================
|
|
306
|
+
# PASO 2: Context7 MCP (Opcional)
|
|
307
|
+
# ============================================
|
|
308
|
+
|
|
309
|
+
if [ "$CONTEXT7_INSTALLED" = false ]; then
|
|
310
|
+
echo -e "${BLUE}📚 Context7 MCP (Opcional)${NC}"
|
|
311
|
+
echo "Context7 permite consultar documentación actualizada de librerías."
|
|
312
|
+
echo ""
|
|
313
|
+
read -p "¿Instalar Context7? (s/n): " INSTALL_CONTEXT7
|
|
314
|
+
|
|
315
|
+
if [[ "$INSTALL_CONTEXT7" =~ ^[Ss]$ ]]; then
|
|
316
|
+
echo ""
|
|
317
|
+
echo -e "${BLUE}📦 Instalando Context7 MCP...${NC}"
|
|
318
|
+
|
|
319
|
+
if npm install -g @context7/mcp-server; then
|
|
320
|
+
echo -e "${GREEN}✅ Context7 MCP instalado${NC}"
|
|
321
|
+
echo ""
|
|
322
|
+
|
|
323
|
+
echo "🔑 Obtén tu API key en: https://context7.com/dashboard"
|
|
324
|
+
read -sp " API Key: " CONTEXT7_KEY
|
|
325
|
+
echo ""
|
|
326
|
+
echo ""
|
|
327
|
+
|
|
328
|
+
if [ -n "$CONTEXT7_KEY" ]; then
|
|
329
|
+
CONTEXT7_INSTALLED=true
|
|
330
|
+
echo -e "${GREEN}✅ Context7 API Key guardada${NC}"
|
|
331
|
+
fi
|
|
332
|
+
else
|
|
333
|
+
echo -e "${RED}❌ Error instalando Context7${NC}"
|
|
334
|
+
fi
|
|
335
|
+
echo ""
|
|
336
|
+
else
|
|
337
|
+
echo -e "${YELLOW}⏭️ Context7 omitido${NC}"
|
|
338
|
+
echo ""
|
|
339
|
+
fi
|
|
340
|
+
else
|
|
341
|
+
echo -e "${GREEN}✅ Context7 ya configurado — Omitiendo${NC}"
|
|
342
|
+
echo ""
|
|
343
|
+
fi
|
|
344
|
+
|
|
345
|
+
# ============================================
|
|
346
|
+
# PASO 3: CodeRabbit Config
|
|
347
|
+
# ============================================
|
|
348
|
+
|
|
349
|
+
if [ "$CODERABBIT_INSTALLED" = false ]; then
|
|
350
|
+
echo -e "${BLUE}🤖 CodeRabbit Config (OBLIGATORIO)${NC}"
|
|
351
|
+
echo ""
|
|
352
|
+
echo "⚠️ CodeRabbit es OBLIGATORIO para mantener calidad del código."
|
|
353
|
+
echo " Hace code review automático en todos los PRs."
|
|
354
|
+
echo ""
|
|
355
|
+
|
|
356
|
+
TEMPLATE_PATH="proyectos/_template/.coderabbit.yaml"
|
|
357
|
+
|
|
358
|
+
if [ -f "$TEMPLATE_PATH" ]; then
|
|
359
|
+
cp "$TEMPLATE_PATH" .coderabbit.yaml
|
|
360
|
+
echo -e "${GREEN}✅ .coderabbit.yaml copiado${NC}"
|
|
361
|
+
echo ""
|
|
362
|
+
echo -e "${YELLOW}📋 Próximo paso (después del setup):${NC}"
|
|
363
|
+
echo " Instala CodeRabbit en GitHub: https://github.com/apps/coderabbitai"
|
|
364
|
+
echo ""
|
|
365
|
+
else
|
|
366
|
+
echo -e "${RED}❌ Template no encontrado: $TEMPLATE_PATH${NC}"
|
|
367
|
+
echo -e "${YELLOW}⚠️ Deberás crear .coderabbit.yaml manualmente${NC}"
|
|
368
|
+
echo ""
|
|
369
|
+
fi
|
|
370
|
+
else
|
|
371
|
+
echo -e "${GREEN}✅ CodeRabbit config ya existe — Omitiendo${NC}"
|
|
372
|
+
echo ""
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
# ============================================
|
|
376
|
+
# PASO 4: Asana (OBLIGATORIO — ÚLTIMO)
|
|
377
|
+
# ============================================
|
|
378
|
+
|
|
379
|
+
if [ "$JIRA_INSTALLED" = false ]; then
|
|
380
|
+
echo -e "${BLUE}🔌 Asana (OBLIGATORIO)${NC}"
|
|
381
|
+
echo ""
|
|
382
|
+
echo "⚠️ Asana es OBLIGATORIO para usar SpecLeap."
|
|
383
|
+
echo " El workflow completo depende de Jira para:"
|
|
384
|
+
echo " - Generar tickets desde CONTRATO"
|
|
385
|
+
echo " - Refinar user stories"
|
|
386
|
+
echo " - Vincular PRs a tickets"
|
|
387
|
+
echo ""
|
|
388
|
+
|
|
389
|
+
SKIP_JSON_CONFIG=false
|
|
390
|
+
|
|
391
|
+
if [ "$IDE" = "vscode" ]; then
|
|
392
|
+
# VSCode: Instalar extensión oficial de Atlassian
|
|
393
|
+
echo -e "${BLUE}📦 Instalando extensión Atlassian para VSCode...${NC}"
|
|
394
|
+
|
|
395
|
+
if code --install-extension Atlassian.atlascode; then
|
|
396
|
+
echo -e "${GREEN}✅ Extensión Atlassian instalada${NC}"
|
|
397
|
+
echo ""
|
|
398
|
+
echo -e "${YELLOW}ℹ️ Configuración de Jira en VSCode:${NC}"
|
|
399
|
+
echo ""
|
|
400
|
+
echo " Después de reiniciar VSCode:"
|
|
401
|
+
echo " 1. Busca el icono de Atlassian en la barra lateral"
|
|
402
|
+
echo " 2. Click en 'Connect' y sigue el flujo OAuth"
|
|
403
|
+
echo ""
|
|
404
|
+
SKIP_JSON_CONFIG=true
|
|
405
|
+
else
|
|
406
|
+
echo -e "${RED}❌ Error instalando extensión de Atlassian${NC}"
|
|
407
|
+
echo -e "${YELLOW}⚠️ Instálala manualmente desde el marketplace de VSCode${NC}"
|
|
408
|
+
exit 1
|
|
409
|
+
fi
|
|
410
|
+
else
|
|
411
|
+
# OpenClaw, Cursor, Continue: Solicitar credenciales
|
|
412
|
+
echo -e "${BLUE}🔐 Configuración de Asana${NC}"
|
|
413
|
+
echo ""
|
|
414
|
+
|
|
415
|
+
read -p "🔗 Jira URL (ej: https://tu-workspace.atlassian.net): " JIRA_URL
|
|
416
|
+
echo ""
|
|
417
|
+
|
|
418
|
+
read -p "📧 Email de Atlassian: " JIRA_EMAIL
|
|
419
|
+
echo ""
|
|
420
|
+
|
|
421
|
+
echo "🔑 API Token (obtener en: https://id.atlassian.com/manage-profile/security/api-tokens)"
|
|
422
|
+
read -sp " Token: " JIRA_TOKEN
|
|
423
|
+
echo ""
|
|
424
|
+
echo ""
|
|
425
|
+
|
|
426
|
+
# Validar inputs
|
|
427
|
+
if [ -z "$JIRA_URL" ] || [ -z "$JIRA_EMAIL" ] || [ -z "$JIRA_TOKEN" ]; then
|
|
428
|
+
echo -e "${RED}❌ Todos los campos son obligatorios${NC}"
|
|
429
|
+
exit 1
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
# Normalizar URL (quitar trailing slash si existe)
|
|
433
|
+
JIRA_URL="${JIRA_URL%/}"
|
|
434
|
+
|
|
435
|
+
echo ""
|
|
436
|
+
echo -e "${BLUE}⚙️ Configurando Asana en $IDE...${NC}"
|
|
437
|
+
fi
|
|
438
|
+
|
|
439
|
+
# Configurar JSON solo para IDEs que no sean VSCode
|
|
440
|
+
if [ "$SKIP_JSON_CONFIG" = false ]; then
|
|
441
|
+
# Backup del config existente
|
|
442
|
+
if [ -f "$CONFIG_PATH" ]; then
|
|
443
|
+
BACKUP_PATH="${CONFIG_PATH}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
444
|
+
cp "$CONFIG_PATH" "$BACKUP_PATH"
|
|
445
|
+
echo -e "${GREEN}✅ Backup creado: $BACKUP_PATH${NC}"
|
|
446
|
+
fi
|
|
447
|
+
|
|
448
|
+
# Configurar según IDE
|
|
449
|
+
case "$IDE" in
|
|
450
|
+
vscode)
|
|
451
|
+
# Verificar si existe el archivo
|
|
452
|
+
if [ ! -f "$CONFIG_PATH" ]; then
|
|
453
|
+
echo -e "${YELLOW}⚠️ $CONFIG_PATH no existe. Creando...${NC}"
|
|
454
|
+
mkdir -p ~/.openclaw
|
|
455
|
+
echo '{"agents":{"main":{}}}' > "$CONFIG_PATH"
|
|
456
|
+
fi
|
|
457
|
+
|
|
458
|
+
# Usar Python para manipular JSON
|
|
459
|
+
python3 - <<EOF
|
|
460
|
+
import json
|
|
461
|
+
|
|
462
|
+
config_path = "$CONFIG_PATH"
|
|
463
|
+
|
|
464
|
+
with open(config_path, 'r') as f:
|
|
465
|
+
config = json.load(f)
|
|
466
|
+
|
|
467
|
+
# Asegurar estructura
|
|
468
|
+
if 'agents' not in config:
|
|
469
|
+
config['agents'] = {}
|
|
470
|
+
if 'main' not in config['agents']:
|
|
471
|
+
config['agents']['main'] = {}
|
|
472
|
+
if 'mcpServers' not in config['agents']['main']:
|
|
473
|
+
config['agents']['main']['mcpServers'] = {}
|
|
474
|
+
|
|
475
|
+
# Agregar Asana
|
|
476
|
+
config['agents']['main']['mcpServers']['jira'] = {
|
|
477
|
+
"command": "asana",
|
|
478
|
+
"args": [],
|
|
479
|
+
"env": {
|
|
480
|
+
"JIRA_URL": "$JIRA_URL",
|
|
481
|
+
"JIRA_EMAIL": "$JIRA_EMAIL",
|
|
482
|
+
"JIRA_API_TOKEN": "$JIRA_TOKEN"
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
# Agregar Context7 si fue instalado
|
|
487
|
+
if $CONTEXT7_INSTALLED:
|
|
488
|
+
config['agents']['main']['mcpServers']['context7'] = {
|
|
489
|
+
"command": "context7-mcp",
|
|
490
|
+
"env": {
|
|
491
|
+
"CONTEXT7_API_KEY": "$CONTEXT7_KEY"
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
# Guardar
|
|
496
|
+
with open(config_path, 'w') as f:
|
|
497
|
+
json.dump(config, f, indent=2)
|
|
498
|
+
|
|
499
|
+
print("✅ Configuración actualizada")
|
|
500
|
+
EOF
|
|
501
|
+
;;
|
|
502
|
+
|
|
503
|
+
cursor)
|
|
504
|
+
# Cursor usa ~/.cursor/config.json
|
|
505
|
+
if [ ! -f "$CONFIG_PATH" ]; then
|
|
506
|
+
mkdir -p ~/.cursor
|
|
507
|
+
echo '{}' > "$CONFIG_PATH"
|
|
508
|
+
fi
|
|
509
|
+
|
|
510
|
+
python3 - <<EOF
|
|
511
|
+
import json
|
|
512
|
+
|
|
513
|
+
config_path = "$CONFIG_PATH"
|
|
514
|
+
|
|
515
|
+
with open(config_path, 'r') as f:
|
|
516
|
+
config = json.load(f)
|
|
517
|
+
|
|
518
|
+
# Asegurar estructura
|
|
519
|
+
if 'mcp' not in config:
|
|
520
|
+
config['mcp'] = {}
|
|
521
|
+
if 'servers' not in config['mcp']:
|
|
522
|
+
config['mcp']['servers'] = {}
|
|
523
|
+
|
|
524
|
+
# Agregar Asana
|
|
525
|
+
config['mcp']['servers']['jira'] = {
|
|
526
|
+
"command": "asana",
|
|
527
|
+
"env": {
|
|
528
|
+
"JIRA_URL": "$JIRA_URL",
|
|
529
|
+
"JIRA_EMAIL": "$JIRA_EMAIL",
|
|
530
|
+
"JIRA_API_TOKEN": "$JIRA_TOKEN"
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
# Agregar Context7 si fue instalado
|
|
535
|
+
if $CONTEXT7_INSTALLED:
|
|
536
|
+
config['mcp']['servers']['context7'] = {
|
|
537
|
+
"command": "context7-mcp",
|
|
538
|
+
"env": {
|
|
539
|
+
"CONTEXT7_API_KEY": "$CONTEXT7_KEY"
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
# Guardar
|
|
544
|
+
with open(config_path, 'w') as f:
|
|
545
|
+
json.dump(config, f, indent=2)
|
|
546
|
+
|
|
547
|
+
print("✅ Configuración actualizada")
|
|
548
|
+
EOF
|
|
549
|
+
;;
|
|
550
|
+
|
|
551
|
+
continue)
|
|
552
|
+
# Continue usa .continue/config.json en el proyecto
|
|
553
|
+
PROJECT_ROOT=$(pwd)
|
|
554
|
+
CONFIG_DIR="$PROJECT_ROOT/.continue"
|
|
555
|
+
CONFIG_PATH="$CONFIG_DIR/config.json"
|
|
556
|
+
|
|
557
|
+
if [ ! -d "$CONFIG_DIR" ]; then
|
|
558
|
+
mkdir -p "$CONFIG_DIR"
|
|
559
|
+
fi
|
|
560
|
+
|
|
561
|
+
if [ ! -f "$CONFIG_PATH" ]; then
|
|
562
|
+
echo '{}' > "$CONFIG_PATH"
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
python3 - <<EOF
|
|
566
|
+
import json
|
|
567
|
+
|
|
568
|
+
config_path = "$CONFIG_PATH"
|
|
569
|
+
|
|
570
|
+
with open(config_path, 'r') as f:
|
|
571
|
+
config = json.load(f)
|
|
572
|
+
|
|
573
|
+
# Asegurar estructura
|
|
574
|
+
if 'mcpServers' not in config:
|
|
575
|
+
config['mcpServers'] = {}
|
|
576
|
+
|
|
577
|
+
# Agregar Asana
|
|
578
|
+
config['mcpServers']['jira'] = {
|
|
579
|
+
"command": "asana",
|
|
580
|
+
"env": {
|
|
581
|
+
"JIRA_URL": "$JIRA_URL",
|
|
582
|
+
"JIRA_EMAIL": "$JIRA_EMAIL",
|
|
583
|
+
"JIRA_API_TOKEN": "$JIRA_TOKEN"
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
# Agregar Context7 si fue instalado
|
|
588
|
+
if $CONTEXT7_INSTALLED:
|
|
589
|
+
config['mcpServers']['context7'] = {
|
|
590
|
+
"command": "context7-mcp",
|
|
591
|
+
"env": {
|
|
592
|
+
"CONTEXT7_API_KEY": "$CONTEXT7_KEY"
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
# Guardar
|
|
597
|
+
with open(config_path, 'w') as f:
|
|
598
|
+
json.dump(config, f, indent=2)
|
|
599
|
+
|
|
600
|
+
print("✅ Configuración actualizada")
|
|
601
|
+
EOF
|
|
602
|
+
;;
|
|
603
|
+
esac
|
|
604
|
+
|
|
605
|
+
echo -e "${GREEN}✅ Asana configurado en $IDE${NC}"
|
|
606
|
+
echo ""
|
|
607
|
+
fi
|
|
608
|
+
else
|
|
609
|
+
echo -e "${GREEN}✅ Asana ya configurado — Omitiendo${NC}"
|
|
610
|
+
echo ""
|
|
611
|
+
fi
|
|
612
|
+
|
|
613
|
+
# ============================================
|
|
614
|
+
# RESUMEN FINAL
|
|
615
|
+
# ============================================
|
|
616
|
+
|
|
617
|
+
echo ""
|
|
618
|
+
echo -e "${GREEN}"
|
|
619
|
+
echo "╔════════════════════════════════════════════╗"
|
|
620
|
+
echo "║ ✅ Setup Completo — Reiniciar ║"
|
|
621
|
+
echo "╔════════════════════════════════════════════╗"
|
|
622
|
+
echo -e "${NC}"
|
|
623
|
+
echo ""
|
|
624
|
+
|
|
625
|
+
echo -e "${BLUE}📋 Estado final:${NC}"
|
|
626
|
+
echo ""
|
|
627
|
+
echo " ✅ Agent Skills TIER 1 — $INSTALLED_COUNT instaladas, $FAILED_COUNT fallidas"
|
|
628
|
+
if [ "$CONTEXT7_INSTALLED" = true ]; then
|
|
629
|
+
echo " ✅ Context7 MCP — Configurado"
|
|
630
|
+
fi
|
|
631
|
+
echo " ✅ CodeRabbit config (.coderabbit.yaml)"
|
|
632
|
+
echo " ✅ Asana — Configurado en $CONFIG_PATH"
|
|
633
|
+
echo ""
|
|
634
|
+
|
|
635
|
+
echo -e "${YELLOW}🔄 Próximos pasos:${NC}"
|
|
636
|
+
echo ""
|
|
637
|
+
echo " 1. ${GREEN}Reinicia $IDE${NC} (cerrar completamente y reabrir)"
|
|
638
|
+
echo " 2. Abre un proyecto de SpecLeap"
|
|
639
|
+
echo " 3. En el chat con la IA, prueba:"
|
|
640
|
+
echo ""
|
|
641
|
+
echo -e " ${GREEN}/refinar SCRUM-1${NC}"
|
|
642
|
+
echo ""
|
|
643
|
+
echo " Si funciona, la IA leerá el ticket de Jira automáticamente."
|
|
644
|
+
echo ""
|
|
645
|
+
|
|
646
|
+
echo -e "${BLUE}📖 Documentación:${NC}"
|
|
647
|
+
echo " • SETUP.md — Troubleshooting completo"
|
|
648
|
+
echo " • README.md — Uso de SpecLeap"
|
|
649
|
+
echo " • .commands/*.md — Referencia de comandos"
|
|
650
|
+
echo " • docs/SKILLS-REFERENCE.md — Guía rápida skills"
|
|
651
|
+
echo ""
|
|
652
|
+
|
|
653
|
+
echo -e "${GREEN}✨ ¡Setup completo! Reinicia $IDE para activar todo.${NC}"
|
|
654
|
+
echo ""
|