elsabro 7.1.0 → 7.3.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.1.0",
3
+ "version": "7.3.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",
@@ -501,7 +501,7 @@ Para verificar que el sistema está correctamente configurado:
501
501
  ### Comandos Core
502
502
  - [ ] `start.md` tiene sección `<enforcement>` y `<state_sync>`
503
503
  - [ ] `plan.md` tiene sección `<state_sync>` y `dispatcher` en frontmatter
504
- - [ ] `execute.md` tiene sección `<state_sync>` y `dispatcher` en frontmatter
504
+ - [ ] `execute.md` tiene sync config en frontmatter y referencia a @references/state-sync.md
505
505
  - [ ] `verify-work.md` tiene sección `<state_sync>` y `dispatcher` en frontmatter
506
506
 
507
507
  ### Referencias
@@ -336,21 +336,13 @@ New "teams" profile added:
336
336
  }
337
337
  ```
338
338
 
339
- ### execute.md Dispatcher
340
-
341
- New fields in dispatcher config:
342
-
343
- ```yaml
344
- dispatcher:
345
- implementation:
346
- method: "agent-team" # v4.2.0: always agent-team for 2+ agents (Rule 8)
347
- agent_team_config:
348
- team_members: [elsabro-executor, elsabro-qa, elsabro-planner]
349
- when: "always" # v4.2.0: mandatory, no longer conditional
350
- verification:
351
- blocking: true
352
- max_review_iterations: 5
353
- ```
339
+ ### execute.md Dispatch (v7.3.0+)
340
+
341
+ execute.md is a thin CLI wrapper. Agent Teams dispatch is in section `#3-dispatch (type: parallel)`.
342
+ The CLI flow engine + `callbacks.js` (`requiresTeam()` / `composeTeam()`) decide automatically
343
+ whether to use Agent Teams (2+ non-haiku branches) or loose subagents (all-haiku).
344
+
345
+ See: `commands/elsabro/execute.md#3-dispatch`
354
346
 
355
347
  ## Changelog (v4.0.0)
356
348