elsabro 2.2.0 → 3.7.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 +668 -20
- package/agents/elsabro-orchestrator.md +113 -0
- package/bin/install.js +0 -0
- package/commands/elsabro/execute.md +223 -46
- package/commands/elsabro/start.md +34 -0
- package/commands/elsabro/verify-work.md +29 -0
- package/flows/development-flow.json +452 -0
- package/flows/quick-flow.json +118 -0
- package/hooks/confirm-destructive.sh +145 -0
- package/hooks/hooks-config.json +81 -0
- package/hooks/lint-check.sh +238 -0
- package/hooks/post-edit-test.sh +189 -0
- package/package.json +5 -3
- package/references/SYSTEM_INDEX.md +379 -5
- package/references/agent-marketplace.md +2274 -0
- package/references/agent-protocol.md +1126 -0
- package/references/ai-code-suggestions.md +2413 -0
- package/references/checkpointing.md +595 -0
- package/references/collaboration-patterns.md +851 -0
- package/references/collaborative-sessions.md +1081 -0
- package/references/configuration-management.md +1810 -0
- package/references/cost-tracking.md +1095 -0
- package/references/enterprise-sso.md +2001 -0
- package/references/error-contracts-tests.md +1171 -0
- package/references/error-contracts-v2.md +968 -0
- package/references/error-contracts.md +3102 -0
- package/references/event-driven.md +1031 -0
- package/references/flow-orchestration.md +940 -0
- package/references/flow-visualization.md +1557 -0
- package/references/ide-integrations.md +3513 -0
- package/references/interrupt-system.md +681 -0
- package/references/kubernetes-deployment.md +3099 -0
- package/references/memory-system.md +683 -0
- package/references/mobile-companion.md +3236 -0
- package/references/multi-llm-providers.md +2494 -0
- package/references/multi-project-memory.md +1182 -0
- package/references/observability.md +793 -0
- package/references/output-schemas.md +858 -0
- package/references/parallel-worktrees.md +293 -0
- package/references/performance-profiler.md +955 -0
- package/references/plugin-system.md +1526 -0
- package/references/prompt-management.md +292 -0
- package/references/sandbox-execution.md +303 -0
- package/references/security-system.md +1253 -0
- package/references/streaming.md +696 -0
- package/references/testing-framework.md +1151 -0
- package/references/time-travel.md +802 -0
- package/references/tool-registry.md +886 -0
- package/references/voice-commands.md +3296 -0
- package/scripts/setup-parallel-worktrees.sh +319 -0
- package/skills/memory-update.md +207 -0
- package/skills/review.md +331 -0
- package/skills/techdebt.md +289 -0
- package/skills/tutor.md +219 -0
- package/templates/.planning/notes/.gitkeep +0 -0
- package/templates/CLAUDE.md.template +48 -0
- package/templates/agent-marketplace-config.json +220 -0
- package/templates/agent-protocol-config.json +136 -0
- package/templates/ai-suggestions-config.json +100 -0
- package/templates/checkpoint-state.json +61 -0
- package/templates/collaboration-config.json +157 -0
- package/templates/collaborative-sessions-config.json +153 -0
- package/templates/configuration-config.json +245 -0
- package/templates/cost-tracking-config.json +148 -0
- package/templates/enterprise-sso-config.json +438 -0
- package/templates/error-handling-config.json +79 -2
- package/templates/events-config.json +148 -0
- package/templates/flow-visualization-config.json +196 -0
- package/templates/ide-integrations-config.json +442 -0
- package/templates/kubernetes-config.json +764 -0
- package/templates/memory-state.json +84 -0
- package/templates/mistakes.md.template +52 -0
- package/templates/mobile-companion-config.json +600 -0
- package/templates/multi-llm-config.json +544 -0
- package/templates/multi-project-memory-config.json +145 -0
- package/templates/observability-config.json +109 -0
- package/templates/patterns.md.template +114 -0
- package/templates/performance-profiler-config.json +125 -0
- package/templates/plugin-config.json +170 -0
- package/templates/prompt-management-config.json +86 -0
- package/templates/sandbox-config.json +185 -0
- package/templates/schemas-config.json +65 -0
- package/templates/security-config.json +120 -0
- package/templates/streaming-config.json +72 -0
- package/templates/testing-config.json +81 -0
- package/templates/timetravel-config.json +62 -0
- package/templates/tool-registry-config.json +109 -0
- package/templates/voice-commands-config.json +658 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# confirm-destructive.sh - ELSABRO Hook: Confirmar antes de operaciones destructivas
|
|
3
|
+
# Uso: Este hook se ejecuta antes de comandos Bash que coinciden con patrones destructivos
|
|
4
|
+
# Patrones: rm -rf, git reset --hard, git clean -fd, git push --force, drop table, truncate
|
|
5
|
+
|
|
6
|
+
# Colores
|
|
7
|
+
RED='\033[0;31m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
YELLOW='\033[1;33m'
|
|
10
|
+
BLUE='\033[0;34m'
|
|
11
|
+
BOLD='\033[1m'
|
|
12
|
+
NC='\033[0m'
|
|
13
|
+
|
|
14
|
+
# Prefijo ELSABRO
|
|
15
|
+
PREFIX="[ELSABRO:hook]"
|
|
16
|
+
|
|
17
|
+
# Comando que se va a ejecutar (pasado como argumento)
|
|
18
|
+
COMMAND="${1:-}"
|
|
19
|
+
|
|
20
|
+
# Patrones destructivos y su descripcion
|
|
21
|
+
declare -A DESTRUCTIVE_PATTERNS=(
|
|
22
|
+
["rm -rf"]="Eliminacion recursiva forzada de archivos/directorios"
|
|
23
|
+
["rm -r"]="Eliminacion recursiva de archivos/directorios"
|
|
24
|
+
["git reset --hard"]="Descarta TODOS los cambios locales sin posibilidad de recuperacion"
|
|
25
|
+
["git clean -fd"]="Elimina archivos no rastreados y directorios"
|
|
26
|
+
["git clean -f"]="Elimina archivos no rastreados"
|
|
27
|
+
["git push --force"]="Sobreescribe historial remoto (puede perder commits de otros)"
|
|
28
|
+
["git push -f"]="Sobreescribe historial remoto (puede perder commits de otros)"
|
|
29
|
+
["DROP TABLE"]="Elimina tabla de base de datos permanentemente"
|
|
30
|
+
["drop table"]="Elimina tabla de base de datos permanentemente"
|
|
31
|
+
["TRUNCATE"]="Elimina todos los datos de una tabla"
|
|
32
|
+
["truncate"]="Elimina todos los datos de una tabla"
|
|
33
|
+
["DELETE FROM"]="Elimina registros de base de datos"
|
|
34
|
+
["delete from"]="Elimina registros de base de datos"
|
|
35
|
+
["> /dev/null"]="Redirige output (potencialmente peligroso si mal usado)"
|
|
36
|
+
["chmod 777"]="Permisos inseguros - todos pueden leer/escribir/ejecutar"
|
|
37
|
+
["chmod -R"]="Cambio recursivo de permisos"
|
|
38
|
+
["dd if="]="Operacion de disco de bajo nivel"
|
|
39
|
+
["mkfs"]="Formateo de sistema de archivos"
|
|
40
|
+
[":(){ :|:& };:"]="Fork bomb - puede crashear el sistema"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Detectar patron destructivo
|
|
44
|
+
detect_destructive_pattern() {
|
|
45
|
+
local cmd="$1"
|
|
46
|
+
|
|
47
|
+
for pattern in "${!DESTRUCTIVE_PATTERNS[@]}"; do
|
|
48
|
+
if [[ "$cmd" == *"$pattern"* ]]; then
|
|
49
|
+
echo "$pattern"
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
echo ""
|
|
55
|
+
return 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Mostrar advertencia
|
|
59
|
+
show_warning() {
|
|
60
|
+
local pattern="$1"
|
|
61
|
+
local description="${DESTRUCTIVE_PATTERNS[$pattern]}"
|
|
62
|
+
|
|
63
|
+
echo ""
|
|
64
|
+
echo -e "${RED}${BOLD}========================================${NC}"
|
|
65
|
+
echo -e "${RED}${BOLD} ADVERTENCIA: OPERACION DESTRUCTIVA${NC}"
|
|
66
|
+
echo -e "${RED}${BOLD}========================================${NC}"
|
|
67
|
+
echo ""
|
|
68
|
+
echo -e "${YELLOW}$PREFIX Comando detectado:${NC}"
|
|
69
|
+
echo -e "${BLUE} $COMMAND${NC}"
|
|
70
|
+
echo ""
|
|
71
|
+
echo -e "${YELLOW}$PREFIX Patron peligroso:${NC} ${RED}$pattern${NC}"
|
|
72
|
+
echo -e "${YELLOW}$PREFIX Riesgo:${NC} $description"
|
|
73
|
+
echo ""
|
|
74
|
+
echo -e "${RED}${BOLD}Este comando puede causar perdida de datos irreversible.${NC}"
|
|
75
|
+
echo ""
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Solicitar confirmacion
|
|
79
|
+
request_confirmation() {
|
|
80
|
+
# En modo no interactivo (CI/CD), rechazar automaticamente
|
|
81
|
+
if [ ! -t 0 ]; then
|
|
82
|
+
echo -e "${RED}$PREFIX Modo no interactivo detectado - rechazando comando destructivo${NC}"
|
|
83
|
+
echo -e "${YELLOW}$PREFIX Para ejecutar en CI, desactiva el hook 'confirm-destructive'${NC}"
|
|
84
|
+
return 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
echo -e "${YELLOW}Para confirmar, escribe exactamente: ${BOLD}SI CONFIRMO${NC}"
|
|
88
|
+
echo -n "> "
|
|
89
|
+
read -r confirmation
|
|
90
|
+
|
|
91
|
+
if [ "$confirmation" = "SI CONFIRMO" ]; then
|
|
92
|
+
echo -e "${GREEN}$PREFIX Confirmado. Procediendo con el comando...${NC}"
|
|
93
|
+
return 0
|
|
94
|
+
else
|
|
95
|
+
echo -e "${RED}$PREFIX Cancelado. El comando NO se ejecutara.${NC}"
|
|
96
|
+
return 1
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Registrar en log
|
|
101
|
+
log_destructive_attempt() {
|
|
102
|
+
local pattern="$1"
|
|
103
|
+
local confirmed="$2"
|
|
104
|
+
local log_dir=".planning/logs"
|
|
105
|
+
local log_file="$log_dir/destructive-commands.log"
|
|
106
|
+
|
|
107
|
+
# Crear directorio si no existe
|
|
108
|
+
mkdir -p "$log_dir" 2>/dev/null || true
|
|
109
|
+
|
|
110
|
+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
111
|
+
local status="REJECTED"
|
|
112
|
+
[ "$confirmed" = "true" ] && status="CONFIRMED"
|
|
113
|
+
|
|
114
|
+
echo "[$timestamp] $status | Pattern: $pattern | Command: $COMMAND" >> "$log_file" 2>/dev/null || true
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# Main
|
|
118
|
+
main() {
|
|
119
|
+
if [ -z "$COMMAND" ]; then
|
|
120
|
+
# Sin comando, permitir (no hay nada que verificar)
|
|
121
|
+
exit 0
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Detectar si es destructivo
|
|
125
|
+
local pattern=$(detect_destructive_pattern "$COMMAND")
|
|
126
|
+
|
|
127
|
+
if [ -z "$pattern" ]; then
|
|
128
|
+
# No es destructivo, permitir
|
|
129
|
+
exit 0
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Es destructivo - mostrar advertencia
|
|
133
|
+
show_warning "$pattern"
|
|
134
|
+
|
|
135
|
+
# Solicitar confirmacion
|
|
136
|
+
if request_confirmation; then
|
|
137
|
+
log_destructive_attempt "$pattern" "true"
|
|
138
|
+
exit 0 # Permitir ejecucion
|
|
139
|
+
else
|
|
140
|
+
log_destructive_attempt "$pattern" "false"
|
|
141
|
+
exit 1 # Bloquear ejecucion
|
|
142
|
+
fi
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main "$@"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"description": "ELSABRO Hooks Configuration - Sistema de hooks automaticos para flujos de trabajo",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"hooks": {
|
|
6
|
+
"PostToolUse": [
|
|
7
|
+
{
|
|
8
|
+
"name": "auto-test-on-edit",
|
|
9
|
+
"description": "Ejecuta tests automaticamente despues de editar codigo",
|
|
10
|
+
"matcher": "Write|Edit",
|
|
11
|
+
"command": "./hooks/post-edit-test.sh",
|
|
12
|
+
"timeout": 30000,
|
|
13
|
+
"enabled": true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "lint-on-save",
|
|
17
|
+
"description": "Ejecuta linter automaticamente despues de escribir",
|
|
18
|
+
"matcher": "Write",
|
|
19
|
+
"command": "./hooks/lint-check.sh",
|
|
20
|
+
"timeout": 10000,
|
|
21
|
+
"enabled": true
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"PreToolUse": [
|
|
25
|
+
{
|
|
26
|
+
"name": "confirm-destructive",
|
|
27
|
+
"description": "Confirmar antes de operaciones destructivas",
|
|
28
|
+
"matcher": "Bash",
|
|
29
|
+
"pattern": "rm -rf|git reset --hard|git clean -fd|git push --force|drop table|truncate",
|
|
30
|
+
"command": "./hooks/confirm-destructive.sh",
|
|
31
|
+
"timeout": 60000,
|
|
32
|
+
"enabled": true
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"Notification": [
|
|
36
|
+
{
|
|
37
|
+
"name": "task-complete-notify",
|
|
38
|
+
"description": "Notifica cuando una tarea larga termina",
|
|
39
|
+
"command": "./hooks/notify-complete.sh",
|
|
40
|
+
"enabled": false
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"profiles": {
|
|
45
|
+
"development": {
|
|
46
|
+
"description": "Perfil balanceado para desarrollo diario",
|
|
47
|
+
"auto-test-on-edit": true,
|
|
48
|
+
"lint-on-save": true,
|
|
49
|
+
"confirm-destructive": true
|
|
50
|
+
},
|
|
51
|
+
"fast": {
|
|
52
|
+
"description": "Perfil rapido sin verificaciones automaticas",
|
|
53
|
+
"auto-test-on-edit": false,
|
|
54
|
+
"lint-on-save": false,
|
|
55
|
+
"confirm-destructive": false
|
|
56
|
+
},
|
|
57
|
+
"careful": {
|
|
58
|
+
"description": "Perfil estricto con todas las verificaciones",
|
|
59
|
+
"auto-test-on-edit": true,
|
|
60
|
+
"lint-on-save": true,
|
|
61
|
+
"confirm-destructive": true
|
|
62
|
+
},
|
|
63
|
+
"ci": {
|
|
64
|
+
"description": "Perfil para integracion continua",
|
|
65
|
+
"auto-test-on-edit": true,
|
|
66
|
+
"lint-on-save": true,
|
|
67
|
+
"confirm-destructive": false
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"settings": {
|
|
71
|
+
"defaultProfile": "development",
|
|
72
|
+
"logHookExecution": true,
|
|
73
|
+
"continueOnHookFailure": false,
|
|
74
|
+
"parallelHooks": false
|
|
75
|
+
},
|
|
76
|
+
"installation": {
|
|
77
|
+
"instructions": "Copia este archivo a ~/.claude/hooks/ o referencia desde settings.json",
|
|
78
|
+
"settingsPath": "~/.claude/settings.json",
|
|
79
|
+
"elsabroPath": ".planning/hooks/"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# lint-check.sh - ELSABRO Hook: Ejecuta linter automaticamente despues de escribir
|
|
3
|
+
# Uso: Este hook se ejecuta automaticamente despues de Write
|
|
4
|
+
# Soporta: eslint, biome, prettier, ruff, flake8, black, clippy, gofmt
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colores
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m'
|
|
14
|
+
|
|
15
|
+
# Prefijo ELSABRO
|
|
16
|
+
PREFIX="[ELSABRO:hook]"
|
|
17
|
+
|
|
18
|
+
# Detectar linter disponible
|
|
19
|
+
detect_linter() {
|
|
20
|
+
# Node.js / JavaScript / TypeScript
|
|
21
|
+
if [ -f "package.json" ]; then
|
|
22
|
+
# Biome (mas rapido, preferido si disponible)
|
|
23
|
+
if grep -q '"@biomejs/biome"' package.json 2>/dev/null || grep -q '"biome"' package.json 2>/dev/null; then
|
|
24
|
+
echo "biome"
|
|
25
|
+
return
|
|
26
|
+
fi
|
|
27
|
+
# ESLint
|
|
28
|
+
if grep -q '"eslint"' package.json 2>/dev/null; then
|
|
29
|
+
echo "eslint"
|
|
30
|
+
return
|
|
31
|
+
fi
|
|
32
|
+
# Prettier (solo formato, no lint)
|
|
33
|
+
if grep -q '"prettier"' package.json 2>/dev/null; then
|
|
34
|
+
echo "prettier"
|
|
35
|
+
return
|
|
36
|
+
fi
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Biome config file
|
|
40
|
+
if [ -f "biome.json" ] || [ -f "biome.jsonc" ]; then
|
|
41
|
+
echo "biome"
|
|
42
|
+
return
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Python
|
|
46
|
+
if [ -f "pyproject.toml" ]; then
|
|
47
|
+
# Ruff (mas rapido, preferido)
|
|
48
|
+
if grep -q '\[tool.ruff\]' pyproject.toml 2>/dev/null || grep -q 'ruff' pyproject.toml 2>/dev/null; then
|
|
49
|
+
if command -v ruff &>/dev/null; then
|
|
50
|
+
echo "ruff"
|
|
51
|
+
return
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
# Black (formatter)
|
|
55
|
+
if grep -q '\[tool.black\]' pyproject.toml 2>/dev/null; then
|
|
56
|
+
if command -v black &>/dev/null; then
|
|
57
|
+
echo "black"
|
|
58
|
+
return
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
# Flake8
|
|
62
|
+
if grep -q 'flake8' pyproject.toml 2>/dev/null; then
|
|
63
|
+
if command -v flake8 &>/dev/null; then
|
|
64
|
+
echo "flake8"
|
|
65
|
+
return
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Python setup.cfg
|
|
71
|
+
if [ -f "setup.cfg" ]; then
|
|
72
|
+
if grep -q '\[flake8\]' setup.cfg 2>/dev/null; then
|
|
73
|
+
if command -v flake8 &>/dev/null; then
|
|
74
|
+
echo "flake8"
|
|
75
|
+
return
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Ruff config file
|
|
81
|
+
if [ -f "ruff.toml" ] || [ -f ".ruff.toml" ]; then
|
|
82
|
+
if command -v ruff &>/dev/null; then
|
|
83
|
+
echo "ruff"
|
|
84
|
+
return
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Rust
|
|
89
|
+
if [ -f "Cargo.toml" ]; then
|
|
90
|
+
echo "clippy"
|
|
91
|
+
return
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Go
|
|
95
|
+
if [ -f "go.mod" ]; then
|
|
96
|
+
echo "gofmt"
|
|
97
|
+
return
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# No linter detected
|
|
101
|
+
echo ""
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Determinar extension del archivo
|
|
105
|
+
get_file_extension() {
|
|
106
|
+
local file="$1"
|
|
107
|
+
echo "${file##*.}"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Verificar si archivo debe ser linteado
|
|
111
|
+
should_lint_file() {
|
|
112
|
+
local file="$1"
|
|
113
|
+
local linter="$2"
|
|
114
|
+
local ext=$(get_file_extension "$file")
|
|
115
|
+
|
|
116
|
+
case "$linter" in
|
|
117
|
+
eslint|biome|prettier)
|
|
118
|
+
[[ "$ext" =~ ^(js|jsx|ts|tsx|mjs|cjs|json)$ ]]
|
|
119
|
+
;;
|
|
120
|
+
ruff|black|flake8)
|
|
121
|
+
[[ "$ext" == "py" ]]
|
|
122
|
+
;;
|
|
123
|
+
clippy)
|
|
124
|
+
[[ "$ext" == "rs" ]]
|
|
125
|
+
;;
|
|
126
|
+
gofmt)
|
|
127
|
+
[[ "$ext" == "go" ]]
|
|
128
|
+
;;
|
|
129
|
+
*)
|
|
130
|
+
return 0
|
|
131
|
+
;;
|
|
132
|
+
esac
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Ejecutar linter
|
|
136
|
+
run_linter() {
|
|
137
|
+
local linter="$1"
|
|
138
|
+
local file="$2"
|
|
139
|
+
|
|
140
|
+
case "$linter" in
|
|
141
|
+
eslint)
|
|
142
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
143
|
+
echo -e "${BLUE}$PREFIX Running eslint on $file...${NC}"
|
|
144
|
+
npx eslint "$file" --fix 2>/dev/null || true
|
|
145
|
+
else
|
|
146
|
+
echo -e "${BLUE}$PREFIX Running eslint (project)...${NC}"
|
|
147
|
+
npx eslint . --fix --ext .js,.jsx,.ts,.tsx 2>/dev/null || true
|
|
148
|
+
fi
|
|
149
|
+
;;
|
|
150
|
+
biome)
|
|
151
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
152
|
+
echo -e "${BLUE}$PREFIX Running biome on $file...${NC}"
|
|
153
|
+
npx @biomejs/biome check --write "$file" 2>/dev/null || npx biome check --apply "$file" 2>/dev/null || true
|
|
154
|
+
else
|
|
155
|
+
echo -e "${BLUE}$PREFIX Running biome (project)...${NC}"
|
|
156
|
+
npx @biomejs/biome check --write . 2>/dev/null || npx biome check --apply 2>/dev/null || true
|
|
157
|
+
fi
|
|
158
|
+
;;
|
|
159
|
+
prettier)
|
|
160
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
161
|
+
echo -e "${BLUE}$PREFIX Running prettier on $file...${NC}"
|
|
162
|
+
npx prettier --write "$file" 2>/dev/null || true
|
|
163
|
+
else
|
|
164
|
+
echo -e "${BLUE}$PREFIX Running prettier (project)...${NC}"
|
|
165
|
+
npx prettier --write . 2>/dev/null || true
|
|
166
|
+
fi
|
|
167
|
+
;;
|
|
168
|
+
ruff)
|
|
169
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
170
|
+
echo -e "${BLUE}$PREFIX Running ruff on $file...${NC}"
|
|
171
|
+
ruff check --fix "$file" 2>/dev/null || true
|
|
172
|
+
ruff format "$file" 2>/dev/null || true
|
|
173
|
+
else
|
|
174
|
+
echo -e "${BLUE}$PREFIX Running ruff (project)...${NC}"
|
|
175
|
+
ruff check --fix . 2>/dev/null || true
|
|
176
|
+
ruff format . 2>/dev/null || true
|
|
177
|
+
fi
|
|
178
|
+
;;
|
|
179
|
+
black)
|
|
180
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
181
|
+
echo -e "${BLUE}$PREFIX Running black on $file...${NC}"
|
|
182
|
+
black "$file" 2>/dev/null || true
|
|
183
|
+
else
|
|
184
|
+
echo -e "${BLUE}$PREFIX Running black (project)...${NC}"
|
|
185
|
+
black . 2>/dev/null || true
|
|
186
|
+
fi
|
|
187
|
+
;;
|
|
188
|
+
flake8)
|
|
189
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
190
|
+
echo -e "${BLUE}$PREFIX Running flake8 on $file...${NC}"
|
|
191
|
+
flake8 "$file" 2>/dev/null
|
|
192
|
+
else
|
|
193
|
+
echo -e "${BLUE}$PREFIX Running flake8 (project)...${NC}"
|
|
194
|
+
flake8 . 2>/dev/null
|
|
195
|
+
fi
|
|
196
|
+
;;
|
|
197
|
+
clippy)
|
|
198
|
+
echo -e "${BLUE}$PREFIX Running cargo clippy...${NC}"
|
|
199
|
+
cargo clippy --fix --allow-dirty --allow-staged 2>/dev/null || true
|
|
200
|
+
;;
|
|
201
|
+
gofmt)
|
|
202
|
+
if [ -n "$file" ] && should_lint_file "$file" "$linter"; then
|
|
203
|
+
echo -e "${BLUE}$PREFIX Running gofmt on $file...${NC}"
|
|
204
|
+
gofmt -w "$file" 2>/dev/null || true
|
|
205
|
+
else
|
|
206
|
+
echo -e "${BLUE}$PREFIX Running gofmt (project)...${NC}"
|
|
207
|
+
gofmt -w . 2>/dev/null || true
|
|
208
|
+
fi
|
|
209
|
+
;;
|
|
210
|
+
*)
|
|
211
|
+
return 0
|
|
212
|
+
;;
|
|
213
|
+
esac
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
main() {
|
|
217
|
+
local changed_file="${1:-}"
|
|
218
|
+
local linter=$(detect_linter)
|
|
219
|
+
|
|
220
|
+
if [ -z "$linter" ]; then
|
|
221
|
+
echo -e "${YELLOW}$PREFIX No linter detected, skipping lint check${NC}"
|
|
222
|
+
exit 0
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
echo -e "${YELLOW}$PREFIX Detected linter: $linter${NC}"
|
|
226
|
+
|
|
227
|
+
if run_linter "$linter" "$changed_file"; then
|
|
228
|
+
echo -e "${GREEN}$PREFIX Linting passed${NC}"
|
|
229
|
+
exit 0
|
|
230
|
+
else
|
|
231
|
+
echo -e "${RED}$PREFIX Linting found issues${NC}"
|
|
232
|
+
# No exit 1 para no bloquear el flujo
|
|
233
|
+
# Los linters con --fix ya arreglaron lo que pudieron
|
|
234
|
+
exit 0
|
|
235
|
+
fi
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
main "$@"
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# post-edit-test.sh - ELSABRO Hook: Ejecuta tests automaticamente despues de editar codigo
|
|
3
|
+
# Uso: Este hook se ejecuta automaticamente despues de Write/Edit
|
|
4
|
+
# Soporta: vitest, jest, mocha, npm-test, pytest, cargo, go
|
|
5
|
+
|
|
6
|
+
set -e
|
|
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
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
# Prefijo ELSABRO
|
|
16
|
+
PREFIX="[ELSABRO:hook]"
|
|
17
|
+
|
|
18
|
+
# Detectar el tipo de proyecto y runner de tests
|
|
19
|
+
detect_test_runner() {
|
|
20
|
+
# Node.js / JavaScript / TypeScript
|
|
21
|
+
if [ -f "package.json" ]; then
|
|
22
|
+
if grep -q '"vitest"' package.json 2>/dev/null; then
|
|
23
|
+
echo "vitest"
|
|
24
|
+
return
|
|
25
|
+
fi
|
|
26
|
+
if grep -q '"jest"' package.json 2>/dev/null; then
|
|
27
|
+
echo "jest"
|
|
28
|
+
return
|
|
29
|
+
fi
|
|
30
|
+
if grep -q '"mocha"' package.json 2>/dev/null; then
|
|
31
|
+
echo "mocha"
|
|
32
|
+
return
|
|
33
|
+
fi
|
|
34
|
+
# Check for test script in package.json
|
|
35
|
+
if grep -q '"test"' package.json 2>/dev/null; then
|
|
36
|
+
# Verify it's not the default npm test
|
|
37
|
+
local test_script=$(grep -o '"test":\s*"[^"]*"' package.json | head -1)
|
|
38
|
+
if [[ ! "$test_script" =~ "Error: no test specified" ]]; then
|
|
39
|
+
echo "npm-test"
|
|
40
|
+
return
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Python
|
|
46
|
+
if [ -f "pytest.ini" ] || [ -f "pyproject.toml" ] || [ -f "setup.py" ]; then
|
|
47
|
+
if command -v pytest &>/dev/null; then
|
|
48
|
+
echo "pytest"
|
|
49
|
+
return
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
if [ -d "tests" ] || [ -d "test" ]; then
|
|
53
|
+
if command -v pytest &>/dev/null; then
|
|
54
|
+
echo "pytest"
|
|
55
|
+
return
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Rust
|
|
60
|
+
if [ -f "Cargo.toml" ]; then
|
|
61
|
+
echo "cargo"
|
|
62
|
+
return
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Go
|
|
66
|
+
if [ -f "go.mod" ]; then
|
|
67
|
+
echo "go"
|
|
68
|
+
return
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# No runner detected
|
|
72
|
+
echo ""
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Encontrar archivo de test relacionado
|
|
76
|
+
find_related_test() {
|
|
77
|
+
local file="$1"
|
|
78
|
+
local basename=$(basename "$file")
|
|
79
|
+
local dirname=$(dirname "$file")
|
|
80
|
+
local name_without_ext="${basename%.*}"
|
|
81
|
+
|
|
82
|
+
# Patrones comunes de archivos de test
|
|
83
|
+
local patterns=(
|
|
84
|
+
"${dirname}/${name_without_ext}.test.ts"
|
|
85
|
+
"${dirname}/${name_without_ext}.test.js"
|
|
86
|
+
"${dirname}/${name_without_ext}.spec.ts"
|
|
87
|
+
"${dirname}/${name_without_ext}.spec.js"
|
|
88
|
+
"${dirname}/__tests__/${name_without_ext}.test.ts"
|
|
89
|
+
"${dirname}/__tests__/${name_without_ext}.test.js"
|
|
90
|
+
"tests/${name_without_ext}_test.py"
|
|
91
|
+
"test/${name_without_ext}_test.py"
|
|
92
|
+
"${dirname}/test_${name_without_ext}.py"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
for pattern in "${patterns[@]}"; do
|
|
96
|
+
if [ -f "$pattern" ]; then
|
|
97
|
+
echo "$pattern"
|
|
98
|
+
return
|
|
99
|
+
fi
|
|
100
|
+
done
|
|
101
|
+
|
|
102
|
+
echo ""
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Ejecutar tests segun el runner detectado
|
|
106
|
+
run_tests() {
|
|
107
|
+
local runner="$1"
|
|
108
|
+
local changed_file="$2"
|
|
109
|
+
local related_test=$(find_related_test "$changed_file")
|
|
110
|
+
|
|
111
|
+
case "$runner" in
|
|
112
|
+
vitest)
|
|
113
|
+
if [ -n "$related_test" ]; then
|
|
114
|
+
echo -e "${BLUE}$PREFIX Running vitest for related test...${NC}"
|
|
115
|
+
npx vitest run "$related_test" --reporter=dot --passWithNoTests 2>/dev/null
|
|
116
|
+
else
|
|
117
|
+
echo -e "${BLUE}$PREFIX Running vitest (all tests)...${NC}"
|
|
118
|
+
npx vitest run --reporter=dot --passWithNoTests 2>/dev/null
|
|
119
|
+
fi
|
|
120
|
+
;;
|
|
121
|
+
jest)
|
|
122
|
+
if [ -n "$related_test" ]; then
|
|
123
|
+
echo -e "${BLUE}$PREFIX Running jest for related test...${NC}"
|
|
124
|
+
npx jest "$related_test" --bail --passWithNoTests --silent 2>/dev/null
|
|
125
|
+
else
|
|
126
|
+
echo -e "${BLUE}$PREFIX Running jest (all tests)...${NC}"
|
|
127
|
+
npx jest --bail --passWithNoTests --silent 2>/dev/null
|
|
128
|
+
fi
|
|
129
|
+
;;
|
|
130
|
+
mocha)
|
|
131
|
+
echo -e "${BLUE}$PREFIX Running mocha...${NC}"
|
|
132
|
+
npx mocha --exit 2>/dev/null
|
|
133
|
+
;;
|
|
134
|
+
npm-test)
|
|
135
|
+
echo -e "${BLUE}$PREFIX Running npm test...${NC}"
|
|
136
|
+
npm test --silent 2>/dev/null || true
|
|
137
|
+
;;
|
|
138
|
+
pytest)
|
|
139
|
+
if [ -n "$related_test" ]; then
|
|
140
|
+
echo -e "${BLUE}$PREFIX Running pytest for related test...${NC}"
|
|
141
|
+
python -m pytest "$related_test" -x -q 2>/dev/null
|
|
142
|
+
else
|
|
143
|
+
echo -e "${BLUE}$PREFIX Running pytest (all tests)...${NC}"
|
|
144
|
+
python -m pytest -x -q --tb=short 2>/dev/null
|
|
145
|
+
fi
|
|
146
|
+
;;
|
|
147
|
+
cargo)
|
|
148
|
+
echo -e "${BLUE}$PREFIX Running cargo test...${NC}"
|
|
149
|
+
cargo test --quiet 2>/dev/null
|
|
150
|
+
;;
|
|
151
|
+
go)
|
|
152
|
+
echo -e "${BLUE}$PREFIX Running go test...${NC}"
|
|
153
|
+
go test ./... -v 2>/dev/null
|
|
154
|
+
;;
|
|
155
|
+
*)
|
|
156
|
+
# No test runner detected
|
|
157
|
+
return 0
|
|
158
|
+
;;
|
|
159
|
+
esac
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# Main
|
|
163
|
+
main() {
|
|
164
|
+
# Archivo que fue editado (pasado como argumento por el hook)
|
|
165
|
+
local changed_file="${1:-}"
|
|
166
|
+
|
|
167
|
+
# Detectar runner
|
|
168
|
+
local runner=$(detect_test_runner)
|
|
169
|
+
|
|
170
|
+
if [ -z "$runner" ]; then
|
|
171
|
+
# No hay test runner, salir silenciosamente
|
|
172
|
+
echo -e "${YELLOW}$PREFIX No test runner detected, skipping tests${NC}"
|
|
173
|
+
exit 0
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
echo -e "${YELLOW}$PREFIX Detected test runner: $runner${NC}"
|
|
177
|
+
|
|
178
|
+
# Ejecutar tests
|
|
179
|
+
if run_tests "$runner" "$changed_file"; then
|
|
180
|
+
echo -e "${GREEN}$PREFIX Tests passed${NC}"
|
|
181
|
+
exit 0
|
|
182
|
+
else
|
|
183
|
+
echo -e "${RED}$PREFIX Tests failed${NC}"
|
|
184
|
+
echo -e "${RED}$PREFIX Fix the failing tests before continuing${NC}"
|
|
185
|
+
exit 1
|
|
186
|
+
fi
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
main "$@"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elsabro",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Sistema de desarrollo AI-powered para Claude Code -
|
|
3
|
+
"version": "3.7.0",
|
|
4
|
+
"description": "Sistema de desarrollo AI-powered para Claude Code - Orquestación avanzada con checkpointing, memoria multi-nivel y flows declarativos",
|
|
5
5
|
"bin": {
|
|
6
6
|
"elsabro": "bin/install.js"
|
|
7
7
|
},
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
"skills",
|
|
13
13
|
"templates",
|
|
14
14
|
"workflows",
|
|
15
|
+
"flows",
|
|
15
16
|
"references",
|
|
16
|
-
"hooks
|
|
17
|
+
"hooks",
|
|
18
|
+
"scripts"
|
|
17
19
|
],
|
|
18
20
|
"keywords": [
|
|
19
21
|
"claude",
|