elsabro 7.0.1 → 7.2.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,224 @@
1
+ #!/bin/bash
2
+ # skill-install.sh - ELSABRO Skill Install Bridge (v1.0.0)
3
+ #
4
+ # Instala skills del vercel-labs/skills registry y valida archivos instalados.
5
+ # Companion de skill-discovery.sh — este script ejecuta lo que discovery recomienda.
6
+ #
7
+ # Comandos:
8
+ # check - Valida accesibilidad del registry (npx skills check)
9
+ # install "<cmd>" - Ejecuta install command con pre-checks y timeout (e.g. npx skills add ...)
10
+ # validate "<name>" - Verifica que skill instalado existe y tiene YAML frontmatter
11
+ #
12
+ # Output: JSON en stdout, logs en stderr
13
+ # Errores: Siempre exit 0, errores comunicados via JSON {"status":"error","message":"..."}
14
+ #
15
+ # Requiere: bash 4+, node/npm (para npx)
16
+
17
+ set -euo pipefail
18
+
19
+ # ============================================================================
20
+ # CONFIGURACION
21
+ # ============================================================================
22
+
23
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
25
+ GLOBAL_SKILLS_DIR="${HOME}/.claude/skills"
26
+ CACHE_FILE="${PROJECT_ROOT}/.cache/skill-discovery-cache.json"
27
+
28
+ NPX_TIMEOUT=30 # segundos para install
29
+ CHECK_TIMEOUT=15 # segundos para check
30
+
31
+ # Portable timeout: use gtimeout (macOS/brew) > timeout (Linux) > no timeout
32
+ if command -v gtimeout >/dev/null 2>&1; then
33
+ TIMEOUT_CMD="gtimeout"
34
+ elif command -v timeout >/dev/null 2>&1; then
35
+ TIMEOUT_CMD="timeout"
36
+ else
37
+ TIMEOUT_CMD=""
38
+ fi
39
+
40
+ run_with_timeout() {
41
+ local secs="$1"; shift
42
+ if [[ -n "$TIMEOUT_CMD" ]]; then
43
+ "$TIMEOUT_CMD" "$secs" "$@"
44
+ else
45
+ "$@"
46
+ fi
47
+ }
48
+
49
+ # Colores para stderr
50
+ RED='\033[0;31m'
51
+ GREEN='\033[0;32m'
52
+ YELLOW='\033[1;33m'
53
+ NC='\033[0m'
54
+ PREFIX="[ELSABRO:install]"
55
+
56
+ # ============================================================================
57
+ # LOGGING (stderr only)
58
+ # ============================================================================
59
+
60
+ log_info() { echo -e "${GREEN}${PREFIX}${NC} $*" >&2; }
61
+ log_warn() { echo -e "${YELLOW}${PREFIX}${NC} $*" >&2; }
62
+ log_error() { echo -e "${RED}${PREFIX}${NC} $*" >&2; }
63
+
64
+ # ============================================================================
65
+ # JSON OUTPUT (stdout only)
66
+ # ============================================================================
67
+
68
+ json_ok() {
69
+ local extra="${1:-}"
70
+ if [[ -n "$extra" ]]; then
71
+ echo "{\"status\":\"ok\",$extra}"
72
+ else
73
+ echo '{"status":"ok"}'
74
+ fi
75
+ }
76
+
77
+ json_error() {
78
+ local msg="$1"
79
+ echo "{\"status\":\"error\",\"message\":\"$msg\"}"
80
+ }
81
+
82
+ # ============================================================================
83
+ # COMMAND: check
84
+ # Validates registry accessibility via npx skills check
85
+ # ============================================================================
86
+
87
+ cmd_check() {
88
+ log_info "Checking registry accessibility..."
89
+
90
+ command -v npx >/dev/null 2>&1 || { json_error "npx not found"; exit 0; }
91
+
92
+ local output
93
+ if output=$(run_with_timeout "$CHECK_TIMEOUT" npx -y skills check 2>&1); then
94
+ log_info "Registry accessible"
95
+ json_ok
96
+ else
97
+ log_error "Registry check failed: $output"
98
+ json_error "registry check failed"
99
+ fi
100
+ }
101
+
102
+ # ============================================================================
103
+ # COMMAND: install <install_cmd>
104
+ # Executes the given install command with pre-checks and timeout
105
+ # ============================================================================
106
+
107
+ cmd_install() {
108
+ local install_cmd="${1:-}"
109
+
110
+ if [[ -z "$install_cmd" ]]; then
111
+ json_error "install command required"
112
+ exit 0
113
+ fi
114
+
115
+ log_info "Installing skill: $install_cmd"
116
+
117
+ # Pre-check: command format (defense-in-depth — only allow npx skills add ...)
118
+ if [[ ! "$install_cmd" =~ ^npx[[:space:]]+((-y|skills|add|--skill|--yes|-g|-a|claude-code|[a-zA-Z0-9/_-]+)[[:space:]]*)+$ ]]; then
119
+ json_error "install command failed format validation"
120
+ exit 0
121
+ fi
122
+
123
+ # Pre-check: npx available
124
+ command -v npx >/dev/null 2>&1 || { json_error "npx not found"; exit 0; }
125
+
126
+ # Pre-check: skills dir exists and is writable
127
+ if [[ ! -d "$GLOBAL_SKILLS_DIR" ]]; then
128
+ mkdir -p "$GLOBAL_SKILLS_DIR" 2>/dev/null || { json_error "$GLOBAL_SKILLS_DIR cannot be created"; exit 0; }
129
+ fi
130
+ test -w "$GLOBAL_SKILLS_DIR" || { json_error "$GLOBAL_SKILLS_DIR not writable"; exit 0; }
131
+
132
+ # Execute install command with timeout
133
+ local output
134
+ if output=$(run_with_timeout "$NPX_TIMEOUT" bash -c "$install_cmd" 2>&1); then
135
+ log_info "Install succeeded"
136
+
137
+ # Extract skill name from command (--skill <name>)
138
+ local skill_name
139
+ skill_name=$(echo "$install_cmd" | sed -n 's/.*--skill \([a-zA-Z0-9_-]*\).*/\1/p')
140
+
141
+ # Invalidate discovery cache (so next run sees skill as installed)
142
+ if [[ -f "$CACHE_FILE" ]]; then
143
+ rm -f "$CACHE_FILE"
144
+ log_info "Discovery cache invalidated"
145
+ fi
146
+
147
+ json_ok "\"skill\":\"$skill_name\""
148
+ else
149
+ local exit_code=$?
150
+ if [[ $exit_code -eq 124 ]]; then
151
+ log_error "Install timed out after ${NPX_TIMEOUT}s"
152
+ json_error "install timed out after ${NPX_TIMEOUT}s"
153
+ else
154
+ log_error "Install failed (exit $exit_code): $output"
155
+ json_error "install failed: $(echo "$output" | tail -1 | tr '"' "'")"
156
+ fi
157
+ fi
158
+ }
159
+
160
+ # ============================================================================
161
+ # COMMAND: validate <skill_name>
162
+ # Checks installed file exists and has YAML frontmatter
163
+ # ============================================================================
164
+
165
+ cmd_validate() {
166
+ local skill_name="${1:-}"
167
+
168
+ if [[ -z "$skill_name" ]]; then
169
+ json_error "skill name required"
170
+ exit 0
171
+ fi
172
+
173
+ log_info "Validating skill: $skill_name"
174
+
175
+ # Check flat file first: ~/.claude/skills/<name>.md
176
+ local flat_path="${GLOBAL_SKILLS_DIR}/${skill_name}.md"
177
+ if [[ -f "$flat_path" ]]; then
178
+ local first_line
179
+ first_line=$(head -1 "$flat_path")
180
+ if [[ "$first_line" == "---" ]]; then
181
+ log_info "Valid skill at $flat_path (YAML frontmatter)"
182
+ json_ok "\"path\":\"$flat_path\",\"has_frontmatter\":true"
183
+ else
184
+ log_warn "File exists but no YAML frontmatter: $flat_path"
185
+ json_ok "\"path\":\"$flat_path\",\"has_frontmatter\":false"
186
+ fi
187
+ return
188
+ fi
189
+
190
+ # Check subdirectory fallback: ~/.claude/skills/<name>/SKILL.md
191
+ local subdir_path="${GLOBAL_SKILLS_DIR}/${skill_name}/SKILL.md"
192
+ if [[ -f "$subdir_path" ]]; then
193
+ local first_line
194
+ first_line=$(head -1 "$subdir_path")
195
+ if [[ "$first_line" == "---" ]]; then
196
+ log_info "Valid skill at $subdir_path (YAML frontmatter)"
197
+ json_ok "\"path\":\"$subdir_path\",\"has_frontmatter\":true"
198
+ else
199
+ log_warn "File exists but no YAML frontmatter: $subdir_path"
200
+ json_ok "\"path\":\"$subdir_path\",\"has_frontmatter\":false"
201
+ fi
202
+ return
203
+ fi
204
+
205
+ log_error "Skill not found: checked $flat_path and $subdir_path"
206
+ json_error "skill file not found after install"
207
+ }
208
+
209
+ # ============================================================================
210
+ # MAIN
211
+ # ============================================================================
212
+
213
+ cmd="${1:-}"
214
+ shift || true
215
+
216
+ case "$cmd" in
217
+ check) cmd_check ;;
218
+ install) cmd_install "$@" ;;
219
+ validate) cmd_validate "$@" ;;
220
+ *)
221
+ json_error "unknown command: $cmd (use: check, install, validate)"
222
+ exit 0
223
+ ;;
224
+ esac
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elsabro",
3
- "version": "7.0.1",
3
+ "version": "7.2.0",
4
4
  "description": "Sistema de desarrollo AI-powered para Claude Code - BMAD Method Integration, Spec-Driven Development, Party Mode, Next Step Suggestions, Stitch UI Design, Agent Teams, blocking code review, orquestación avanzada con flows declarativos",
5
5
  "bin": {
6
6
  "elsabro": "bin/install.js",
@@ -14,26 +14,26 @@ Los comandos ELSABRO se sincronizan a través de un sistema de estado compartido
14
14
  │ (Entry Point - Orquestador) │
15
15
  └─────────────────────────┬───────────────────────────────────────────┘
16
16
 
17
- ┌───────────────┼───────────────┬───────────────┐
18
- ▼ ▼ ▼ ▼
19
- ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
20
- │ :new │ │ :plan │ │ :debug │ │ :quick │
21
- │ Proyecto │ │ Feature │ │ Bugs │ │ Rápido │
22
- │ nuevo │ │ nueva │ │ │ │ │
23
- └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
24
- │ │ │ │
25
- ▼ ▼ ▼ ▼
26
- ┌──────────┐ ┌──────────┐ ┌──────────┐ │
27
- │ :execute │◄───│ :execute │◄───│ :execute │ │
28
- │ │ │ │ │ │ │
29
- └────┬─────┘ └────┬─────┘ └────┬─────┘ │
30
- │ │ │ │
31
- └───────────────┴───────────────┴───────────────┘
32
-
33
-
34
- ┌──────────────┐
35
- │ :verify-work
36
- │ (Siempre) │
17
+ ┌───────────────┬───┼───────────────┬───────────────┐
18
+ ▼ ▼ ▼ ▼
19
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐
20
+ │ :new │ │ :plan │ │ :debug │ │ :quick │ │ :design-ui │
21
+ │ Proyecto │ │ Feature │ │ Bugs │ │ Rápido │ │ Diseño │
22
+ │ nuevo │ │ nueva │ │ │ │ │ │ visual │
23
+ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘
24
+ │ │ │ │
25
+ ▼ ▼ ▼ ▼
26
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
27
+ │ :execute │◄───│ :execute │◄───│ :execute │ │ ┌─────┘
28
+ │ │ │ │ │ │ │
29
+ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
30
+ │ │ │ │
31
+ └───────────────┴───────────────┴───────────────┘
32
+
33
+
34
+ ┌──────────────┐
35
+ │ :verify-work │◄──────────────────────┘
36
+ │ (Siempre) │ (o :execute / :plan)
37
37
  └──────────────┘
38
38
  ```
39
39
 
@@ -202,6 +202,7 @@ start → new ✓ (proyecto nuevo)
202
202
  start → plan ✓ (feature en proyecto existente)
203
203
  start → debug ✓ (resolver problema)
204
204
  start → quick ✓ (tarea simple)
205
+ start → design-ui ✓ (explorar visualmente / diseñar interfaz)
205
206
 
206
207
  new → plan ✓ (siguiente paso natural)
207
208
  new → execute ✗ (necesita plan primero)
@@ -220,6 +221,10 @@ debug → plan ✓ (fix complejo necesita plan)
220
221
 
221
222
  quick → verify ✓ (verificar tarea rápida)
222
223
  quick → [done] ✓ (tarea completada)
224
+
225
+ design-ui → plan ✓ (planificar implementación de diseños)
226
+ design-ui → execute ✓ (implementar diseños directamente)
227
+ design-ui → [done] ✓ (solo diseñar por ahora)
223
228
  ```
224
229
 
225
230
  ---