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.
Files changed (47) hide show
  1. package/.agents/backend.md +419 -0
  2. package/.agents/frontend.md +577 -0
  3. package/.agents/producto.md +516 -0
  4. package/.commands/adoptar.md +323 -0
  5. package/.commands/ayuda.md +142 -0
  6. package/.commands/crear-tickets.md +55 -0
  7. package/.commands/documentar.md +285 -0
  8. package/.commands/explicar.md +234 -0
  9. package/.commands/implementar.md +383 -0
  10. package/.commands/inicio.md +824 -0
  11. package/.commands/nuevo/README.md +292 -0
  12. package/.commands/nuevo/questions-base.yaml +320 -0
  13. package/.commands/nuevo/responses-example.yaml +53 -0
  14. package/.commands/planificar.md +253 -0
  15. package/.commands/refinar.md +306 -0
  16. package/LICENSE +21 -0
  17. package/README.md +603 -0
  18. package/SETUP.md +351 -0
  19. package/install.sh +152 -0
  20. package/package.json +60 -0
  21. package/proyectos/_template/.gitkeep +1 -0
  22. package/proyectos/_template/ANEXOS.md +21 -0
  23. package/proyectos/_template/CONTRATO.md +26 -0
  24. package/proyectos/_template/context/.gitkeep +1 -0
  25. package/rules/development-rules.md +113 -0
  26. package/rules/environment-protection.md +97 -0
  27. package/rules/git-workflow.md +142 -0
  28. package/rules/session-protocol.md +121 -0
  29. package/scripts/README.md +129 -0
  30. package/scripts/analyze-project.sh +826 -0
  31. package/scripts/create-asana-tasks.sh +133 -0
  32. package/scripts/detect-project-type.sh +141 -0
  33. package/scripts/estimate-effort.sh +290 -0
  34. package/scripts/generate-asana-structure.sh +262 -0
  35. package/scripts/generate-contract.sh +360 -0
  36. package/scripts/generate-contrato.sh +555 -0
  37. package/scripts/install-git-hooks.sh +141 -0
  38. package/scripts/install-skills.sh +130 -0
  39. package/scripts/lib/asana-utils.sh +191 -0
  40. package/scripts/lib/jira-project-utils.sh +222 -0
  41. package/scripts/lib/questions.json +831 -0
  42. package/scripts/lib/render-contrato.py +195 -0
  43. package/scripts/lib/validate.sh +325 -0
  44. package/scripts/parse-contrato.sh +190 -0
  45. package/scripts/setup-mcp.sh +654 -0
  46. package/scripts/test-cuestionario.sh +428 -0
  47. package/setup.sh +458 -0
@@ -0,0 +1,130 @@
1
+ #!/bin/bash
2
+ # SpecLeap — Instalador de Agent Skills TIER 1
3
+ # Versión 2.0 — Robusto y con progreso visual
4
+
5
+ set -e
6
+
7
+ GREEN='\033[0;32m'
8
+ RED='\033[0;31m'
9
+ YELLOW='\033[1;33m'
10
+ BLUE='\033[0;34m'
11
+ NC='\033[0m'
12
+
13
+ echo -e "${BLUE}━━━ Installing Agent Skills TIER 1 ━━━${NC}"
14
+ echo ""
15
+
16
+ # Lista de skills (repo:path:name)
17
+ SKILLS=(
18
+ # Consistencia (3) - obra/superpowers
19
+ "obra/superpowers:skills/verification-before-completion:verification-before-completion"
20
+ "obra/superpowers:skills/systematic-debugging:systematic-debugging"
21
+ "obra/superpowers:skills/requesting-code-review:requesting-code-review"
22
+
23
+ # Backend (7) - jeffallan/claude-skills
24
+ "jeffallan/claude-skills:skills/laravel-specialist:laravel-specialist"
25
+ "jeffallan/claude-skills:skills/api-designer:api-designer"
26
+ "jeffallan/claude-skills:skills/database-optimizer:database-optimizer"
27
+ "jeffallan/claude-skills:skills/code-reviewer:code-reviewer"
28
+ "jeffallan/claude-skills:skills/debugging-wizard:debugging-wizard"
29
+ "jeffallan/claude-skills:skills/python-pro:python-pro"
30
+ "jeffallan/claude-skills:skills/react-expert:react-expert"
31
+
32
+ # Diseño (4) - anthropics/skills
33
+ "anthropics/skills:skills/frontend-design:frontend-design"
34
+ "anthropics/skills:skills/skill-creator:skill-creator"
35
+ "anthropics/skills:skills/canvas-design:canvas-design"
36
+ "anthropics/skills:skills/algorithmic-art:algorithmic-art"
37
+
38
+ # DevOps (3) - jeffallan/claude-skills
39
+ "jeffallan/claude-skills:skills/devops-engineer:devops-engineer"
40
+ "jeffallan/claude-skills:skills/cloud-architect:cloud-architect"
41
+ "jeffallan/claude-skills:skills/architecture-designer:architecture-designer"
42
+
43
+ # Testing (2) - obra/superpowers
44
+ "obra/superpowers:skills/test-driven-development:test-driven-development"
45
+ "obra/superpowers:skills/receiving-code-review:receiving-code-review"
46
+
47
+ # Frontend (1) - jeffallan/claude-skills
48
+ "jeffallan/claude-skills:skills/typescript-pro:typescript-pro"
49
+ )
50
+
51
+ TOTAL=${#SKILLS[@]}
52
+ INSTALLED=0
53
+ FAILED=0
54
+ SKIPPED=0
55
+
56
+ SKILLS_DIR="$HOME/.skills"
57
+ TMP_DIR="/tmp/specleap-skills-$$"
58
+
59
+ mkdir -p "$SKILLS_DIR"
60
+ mkdir -p "$TMP_DIR"
61
+
62
+ # Función para limpiar temporal
63
+ cleanup() {
64
+ rm -rf "$TMP_DIR"
65
+ }
66
+ trap cleanup EXIT
67
+
68
+ echo -e "Installing to: ${GREEN}$SKILLS_DIR${NC}"
69
+ echo ""
70
+
71
+ for i in "${!SKILLS[@]}"; do
72
+ IFS=':' read -r repo path name <<< "${SKILLS[$i]}"
73
+ num=$((i + 1))
74
+
75
+ printf " [%2d/%2d] %-40s " "$num" "$TOTAL" "$name"
76
+
77
+ # Skip si ya existe
78
+ if [ -d "$SKILLS_DIR/$name" ]; then
79
+ echo -e "${YELLOW}SKIP${NC} (already installed)"
80
+ ((SKIPPED++))
81
+ continue
82
+ fi
83
+
84
+ # Clonar repo si no existe
85
+ repo_dir="$TMP_DIR/$(echo $repo | tr '/' '_')"
86
+ if [ ! -d "$repo_dir" ]; then
87
+ if ! git clone -q "https://github.com/$repo.git" "$repo_dir" 2>/dev/null; then
88
+ echo -e "${RED}FAIL${NC} (repo not accessible)"
89
+ ((FAILED++))
90
+ continue
91
+ fi
92
+ fi
93
+
94
+ # Verificar SKILL.md
95
+ if [ ! -f "$repo_dir/$path/SKILL.md" ]; then
96
+ echo -e "${RED}FAIL${NC} (SKILL.md not found)"
97
+ ((FAILED++))
98
+ continue
99
+ fi
100
+
101
+ # Copiar skill
102
+ cp -r "$repo_dir/$path" "$SKILLS_DIR/$name"
103
+ echo -e "${GREEN}OK${NC}"
104
+ ((INSTALLED++))
105
+ done
106
+
107
+ echo ""
108
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
109
+ echo ""
110
+ echo -e "${GREEN}✅ Installed:${NC} $INSTALLED"
111
+ if [ $SKIPPED -gt 0 ]; then
112
+ echo -e "${YELLOW}⚠️ Skipped:${NC} $SKIPPED (already existed)"
113
+ fi
114
+ if [ $FAILED -gt 0 ]; then
115
+ echo -e "${RED}❌ Failed:${NC} $FAILED"
116
+ fi
117
+ echo ""
118
+
119
+ if [ $INSTALLED -eq 0 ] && [ $SKIPPED -eq $TOTAL ]; then
120
+ echo -e "${GREEN}All skills already installed!${NC}"
121
+ exit 0
122
+ fi
123
+
124
+ if [ $FAILED -gt 0 ]; then
125
+ echo -e "${YELLOW}Warning: Some skills failed to install${NC}"
126
+ echo "This may affect code quality. Check network connection and try again."
127
+ exit 1
128
+ fi
129
+
130
+ echo -e "${GREEN}Agent Skills installation complete!${NC}"
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # SpecLeap — Utilidades para Asana API
4
+ # Funciones helper para interactuar con Asana
5
+
6
+ # Verificar token
7
+ asana_check_auth() {
8
+ if [[ -z "${ASANA_ACCESS_TOKEN:-}" ]]; then
9
+ echo "❌ Error: ASANA_ACCESS_TOKEN no configurado" >&2
10
+ return 1
11
+ fi
12
+ }
13
+
14
+ # Obtener workspace por defecto
15
+ asana_get_default_workspace() {
16
+ asana_check_auth || return 1
17
+
18
+ local response=$(curl -s \
19
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
20
+ "https://app.asana.com/api/1.0/users/me")
21
+
22
+ echo "$response" | jq -r '.data.workspaces[0].gid'
23
+ }
24
+
25
+ # Crear proyecto
26
+ # Uso: asana_create_project "Nombre del Proyecto"
27
+ asana_create_project() {
28
+ local project_name="$1"
29
+ asana_check_auth || return 1
30
+
31
+ if [[ -z "${ASANA_WORKSPACE_GID:-}" ]]; then
32
+ echo "❌ Error: ASANA_WORKSPACE_GID no configurado" >&2
33
+ return 1
34
+ fi
35
+
36
+ local payload=$(jq -n \
37
+ --arg name "$project_name" \
38
+ --arg workspace "$ASANA_WORKSPACE_GID" \
39
+ '{
40
+ data: {
41
+ name: $name,
42
+ workspace: $workspace,
43
+ notes: "Proyecto generado por SpecLeap",
44
+ color: "dark-blue",
45
+ layout: "list"
46
+ }
47
+ }')
48
+
49
+ local response=$(curl -s \
50
+ -X POST \
51
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
52
+ -H "Content-Type: application/json" \
53
+ -d "$payload" \
54
+ "https://app.asana.com/api/1.0/projects")
55
+
56
+ local project_gid=$(echo "$response" | jq -r '.data.gid')
57
+
58
+ if [[ "$project_gid" == "null" || -z "$project_gid" ]]; then
59
+ echo "❌ Error al crear proyecto: $(echo "$response" | jq -r '.errors[0].message')" >&2
60
+ return 1
61
+ fi
62
+
63
+ echo "$project_gid"
64
+ }
65
+
66
+ # Crear sección en un proyecto
67
+ # Uso: asana_create_section "PROJECT_GID" "Nombre Sección"
68
+ asana_create_section() {
69
+ local project_gid="$1"
70
+ local section_name="$2"
71
+ asana_check_auth || return 1
72
+
73
+ local payload=$(jq -n \
74
+ --arg name "$section_name" \
75
+ '{
76
+ data: {
77
+ name: $name
78
+ }
79
+ }')
80
+
81
+ local response=$(curl -s \
82
+ -X POST \
83
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
84
+ -H "Content-Type: application/json" \
85
+ -d "$payload" \
86
+ "https://app.asana.com/api/1.0/projects/$project_gid/sections")
87
+
88
+ local section_gid=$(echo "$response" | jq -r '.data.gid')
89
+
90
+ if [[ "$section_gid" == "null" || -z "$section_gid" ]]; then
91
+ echo "❌ Error al crear sección: $(echo "$response" | jq -r '.errors[0].message')" >&2
92
+ return 1
93
+ fi
94
+
95
+ echo "$section_gid"
96
+ }
97
+
98
+ # Crear tarea
99
+ # Uso: asana_create_task "PROJECT_GID" "Nombre Tarea" "SECTION_GID" POINTS
100
+ asana_create_task() {
101
+ local project_gid="$1"
102
+ local task_name="$2"
103
+ local section_gid="${3:-}"
104
+ local points="${4:-3}"
105
+ asana_check_auth || return 1
106
+
107
+ local payload=$(jq -n \
108
+ --arg name "$task_name" \
109
+ --arg project "$project_gid" \
110
+ --arg points "$points" \
111
+ '{
112
+ data: {
113
+ name: $name,
114
+ projects: [$project],
115
+ notes: ("Story Points: " + $points)
116
+ }
117
+ }')
118
+
119
+ local response=$(curl -s \
120
+ -X POST \
121
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
122
+ -H "Content-Type: application/json" \
123
+ -d "$payload" \
124
+ "https://app.asana.com/api/1.0/tasks")
125
+
126
+ local task_gid=$(echo "$response" | jq -r '.data.gid')
127
+
128
+ if [[ "$task_gid" == "null" || -z "$task_gid" ]]; then
129
+ echo "❌ Error al crear tarea: $(echo "$response" | jq -r '.errors[0].message')" >&2
130
+ return 1
131
+ fi
132
+
133
+ # Si se especificó sección, mover la tarea ahí
134
+ if [[ -n "$section_gid" ]]; then
135
+ curl -s \
136
+ -X POST \
137
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
138
+ -H "Content-Type: application/json" \
139
+ -d "{\"data\": {\"task\": \"$task_gid\"}}" \
140
+ "https://app.asana.com/api/1.0/sections/$section_gid/addTask" \
141
+ > /dev/null
142
+ fi
143
+
144
+ echo "$task_gid"
145
+ }
146
+
147
+ # Listar proyectos
148
+ asana_list_projects() {
149
+ asana_check_auth || return 1
150
+
151
+ if [[ -z "${ASANA_WORKSPACE_GID:-}" ]]; then
152
+ echo "❌ Error: ASANA_WORKSPACE_GID no configurado" >&2
153
+ return 1
154
+ fi
155
+
156
+ curl -s \
157
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
158
+ "https://app.asana.com/api/1.0/projects?workspace=$ASANA_WORKSPACE_GID" \
159
+ | jq -r '.data[] | "\(.gid)\t\(.name)"'
160
+ }
161
+
162
+ # Buscar proyecto por nombre
163
+ # Uso: asana_find_project "Nombre"
164
+ asana_find_project() {
165
+ local project_name="$1"
166
+ asana_list_projects | grep -i "$project_name" | head -1 | cut -f1
167
+ }
168
+
169
+ # Listar secciones de un proyecto
170
+ # Uso: asana_list_sections "PROJECT_GID"
171
+ asana_list_sections() {
172
+ local project_gid="$1"
173
+ asana_check_auth || return 1
174
+
175
+ curl -s \
176
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
177
+ "https://app.asana.com/api/1.0/projects/$project_gid/sections" \
178
+ | jq -r '.data[] | "\(.gid)\t\(.name)"'
179
+ }
180
+
181
+ # Listar tareas de un proyecto
182
+ # Uso: asana_list_tasks "PROJECT_GID"
183
+ asana_list_tasks() {
184
+ local project_gid="$1"
185
+ asana_check_auth || return 1
186
+
187
+ curl -s \
188
+ -H "Authorization: Bearer $ASANA_ACCESS_TOKEN" \
189
+ "https://app.asana.com/api/1.0/projects/$project_gid/tasks" \
190
+ | jq -r '.data[] | "\(.gid)\t\(.name)"'
191
+ }
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # SpecLeap — Utilidades para gestión de proyectos Jira
4
+ # Funciones para crear/verificar proyectos Jira independientes
5
+
6
+ set -euo pipefail
7
+
8
+ # Colores
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ CYAN='\033[0;36m'
13
+ RESET='\033[0m'
14
+
15
+ print_success() {
16
+ echo -e "${GREEN}✅ $1${RESET}" >&2
17
+ }
18
+
19
+ print_error() {
20
+ echo -e "${RED}❌ Error: $1${RESET}" >&2
21
+ }
22
+
23
+ print_warning() {
24
+ echo -e "${YELLOW}⚠️ $1${RESET}" >&2
25
+ }
26
+
27
+ print_info() {
28
+ echo -e "${CYAN}ℹ️ $1${RESET}" >&2
29
+ }
30
+
31
+ # ============================================================================
32
+ # GENERACIÓN DE PROJECT KEY
33
+ # ============================================================================
34
+
35
+ generate_project_key() {
36
+ local project_name="$1"
37
+
38
+ # Convertir nombre a key válida de Jira:
39
+ # - Solo mayúsculas
40
+ # - Sin guiones ni espacios (reemplazar con nada)
41
+ # - Máximo 10 caracteres
42
+ # - Mínimo 2 caracteres
43
+
44
+ # Ejemplos:
45
+ # "casa-de-peli" → "CASADEPELI" → "CASADEPEL" (10 chars)
46
+ # "mi-app" → "MIAPP" (5 chars)
47
+ # "e-commerce" → "ECOMMERCE" → "ECOMMERCE" (9 chars)
48
+
49
+ local key=$(echo "$project_name" | tr '[:lower:]' '[:upper:]' | tr -d '-_ ' | head -c 10)
50
+
51
+ # Validar longitud mínima
52
+ if [[ ${#key} -lt 2 ]]; then
53
+ print_error "Project key muy corto: $key (mínimo 2 caracteres)"
54
+ return 1
55
+ fi
56
+
57
+ echo "$key"
58
+ }
59
+
60
+ # ============================================================================
61
+ # VERIFICACIÓN DE PROYECTO JIRA
62
+ # ============================================================================
63
+
64
+ jira_project_exists() {
65
+ local project_key="$1"
66
+
67
+ # Intentar obtener info del proyecto vía MCP Jira
68
+ # Si el proyecto no existe, el comando fallará
69
+
70
+ # Método 1: Usar MCP Jira (si está configurado)
71
+ if command -v mcp-jira &> /dev/null; then
72
+ if mcp-jira get-project "$project_key" &> /dev/null; then
73
+ return 0 # Proyecto existe
74
+ else
75
+ return 1 # Proyecto no existe
76
+ fi
77
+ fi
78
+
79
+ # Método 2: Usar Jira CLI (si está instalado)
80
+ if command -v jira &> /dev/null; then
81
+ if jira project view "$project_key" &> /dev/null 2>&1; then
82
+ return 0
83
+ else
84
+ return 1
85
+ fi
86
+ fi
87
+
88
+ # Método 3: Verificación manual (sin herramientas)
89
+ print_warning "No se puede verificar proyecto automáticamente (MCP Jira no encontrado)"
90
+ print_info "Por favor verifica manualmente si el proyecto $project_key existe en Jira"
91
+
92
+ # Preguntar al usuario
93
+ read -p "¿El proyecto $project_key existe en Jira? [s/N]: " -n 1 -r >&2
94
+ echo >&2
95
+
96
+ if [[ $REPLY =~ ^[Ss]$ ]]; then
97
+ return 0
98
+ else
99
+ return 1
100
+ fi
101
+ }
102
+
103
+ # ============================================================================
104
+ # CREACIÓN DE PROYECTO JIRA
105
+ # ============================================================================
106
+
107
+ create_jira_project() {
108
+ local project_key="$1"
109
+ local project_name="$2"
110
+ local project_description="$3"
111
+ local lead_email="${4:-}" # Opcional
112
+
113
+ print_info "Intentando crear proyecto Jira: $project_key ($project_name)"
114
+
115
+ # Método 1: Usar MCP Jira (si está configurado)
116
+ if command -v mcp-jira &> /dev/null; then
117
+ print_info "Usando MCP Jira para crear proyecto..."
118
+
119
+ if mcp-jira create-project \
120
+ --key "$project_key" \
121
+ --name "$project_name" \
122
+ --description "$project_description" \
123
+ --type scrum \
124
+ ${lead_email:+--lead "$lead_email"} 2>&1; then
125
+
126
+ print_success "Proyecto $project_key creado exitosamente"
127
+ return 0
128
+ else
129
+ print_error "Fallo al crear proyecto con MCP Jira"
130
+ return 1
131
+ fi
132
+ fi
133
+
134
+ # Método 2: Usar Jira CLI (si está instalado)
135
+ if command -v jira &> /dev/null; then
136
+ print_info "Usando Jira CLI para crear proyecto..."
137
+
138
+ if jira project create \
139
+ --key "$project_key" \
140
+ --name "$project_name" \
141
+ --template "Scrum software development" \
142
+ ${lead_email:+--lead "$lead_email"} 2>&1; then
143
+
144
+ print_success "Proyecto $project_key creado exitosamente"
145
+ return 0
146
+ else
147
+ print_error "Fallo al crear proyecto con Jira CLI"
148
+ return 1
149
+ fi
150
+ fi
151
+
152
+ # Método 3: Instrucciones manuales (sin herramientas)
153
+ print_warning "No se puede crear proyecto automáticamente (herramientas no encontradas)"
154
+ print_info ""
155
+ print_info "Por favor crea el proyecto manualmente en Jira:"
156
+ print_info ""
157
+ print_info " 1. Ve a Jira → Proyectos → Crear proyecto"
158
+ print_info " 2. Selecciona: Scrum software development"
159
+ print_info " 3. Clave del proyecto: $project_key"
160
+ print_info " 4. Nombre del proyecto: $project_name"
161
+ print_info " 5. Descripción: $project_description"
162
+ print_info ""
163
+
164
+ read -p "¿Ya creaste el proyecto $project_key en Jira? [s/N]: " -n 1 -r >&2
165
+ echo >&2
166
+
167
+ if [[ $REPLY =~ ^[Ss]$ ]]; then
168
+ print_success "Proyecto $project_key confirmado"
169
+ return 0
170
+ else
171
+ print_error "Operación cancelada. Crea el proyecto en Jira y vuelve a ejecutar."
172
+ return 1
173
+ fi
174
+ }
175
+
176
+ # ============================================================================
177
+ # FLUJO COMPLETO: VERIFICAR O CREAR PROYECTO
178
+ # ============================================================================
179
+
180
+ ensure_jira_project_exists() {
181
+ local project_key="$1"
182
+ local project_name="$2"
183
+ local project_description="$3"
184
+ local lead_email="${4:-}" # Opcional
185
+
186
+ print_info "Verificando proyecto Jira: $project_key"
187
+
188
+ if jira_project_exists "$project_key"; then
189
+ print_success "Proyecto $project_key ya existe"
190
+ return 0
191
+ else
192
+ print_warning "Proyecto $project_key no existe. Creando..."
193
+
194
+ if create_jira_project "$project_key" "$project_name" "$project_description" "$lead_email"; then
195
+ return 0
196
+ else
197
+ print_error "No se pudo crear el proyecto $project_key"
198
+ return 1
199
+ fi
200
+ fi
201
+ }
202
+
203
+ # ============================================================================
204
+ # VALIDACIÓN DE KEY
205
+ # ============================================================================
206
+
207
+ validate_project_key() {
208
+ local key="$1"
209
+
210
+ # Reglas de Jira para project keys:
211
+ # - Solo letras mayúsculas (A-Z)
212
+ # - Longitud: 2-10 caracteres
213
+ # - Debe empezar con letra
214
+
215
+ if [[ ! "$key" =~ ^[A-Z][A-Z0-9]{1,9}$ ]]; then
216
+ print_error "Project key inválida: $key"
217
+ print_error "Debe contener solo mayúsculas, 2-10 caracteres, empezar con letra"
218
+ return 1
219
+ fi
220
+
221
+ return 0
222
+ }