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.
- package/README.md +155 -887
- package/commands/elsabro/execute.md +121 -10
- package/commands/elsabro/party.md +87 -2
- package/commands/elsabro/start.md +9 -3
- package/flow-engine/src/party.js +29 -3
- package/flow-engine/tests/cli.test.js +2 -2
- package/flow-engine/tests/graph.test.js +1 -1
- package/flow-engine/tests/integration.test.js +7 -7
- package/flow-engine/tests/party.test.js +57 -0
- package/flow-engine/tests/runner.test.js +457 -0
- package/flow-engine/tests/skill-install.test.js +374 -0
- package/flows/development-flow.json +42 -5
- package/flows/quick-flow.json +0 -1
- package/hooks/skill-discovery.sh +6 -4
- package/hooks/skill-install.sh +224 -0
- package/package.json +1 -1
- package/references/command-flow.md +25 -20
|
@@ -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
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
└────┬─────┘ └────┬─────┘ └────┬─────┘
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
---
|