evol-dd 0.1.0__py3-none-any.whl
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.
- evol_cli/VERSION +1 -0
- evol_cli/__init__.py +173 -0
- evol_cli/agent/hooks/hooks.json +78 -0
- evol_cli/agent/hooks/scripts/.gitkeep +0 -0
- evol_cli/agent/hooks/scripts/post-bash-pr-logger.sh +9 -0
- evol_cli/agent/hooks/scripts/post-edit-mempalace-index.sh +7 -0
- evol_cli/agent/hooks/scripts/post-write-auto-organize.sh +13 -0
- evol_cli/agent/hooks/scripts/pre-bash-dangerous-command.sh +105 -0
- evol_cli/agent/hooks/scripts/pre-commit-gitflow.sh +25 -0
- evol_cli/agent/hooks/scripts/pre-edit-config-protection.sh +53 -0
- evol_cli/agent/hooks/scripts/pre-tool-temporal-awareness.sh +8 -0
- evol_cli/agent/hooks/scripts/pre-write-doc-file-warning.sh +19 -0
- evol_cli/agent/hooks/scripts/session-start-context-load.sh +17 -0
- evol_cli/agent/hooks/scripts/session-start-reme-load.sh +20 -0
- evol_cli/agent/hooks/scripts/stop-git-check.sh +11 -0
- evol_cli/agent/hooks/scripts/stop-pattern-extraction.sh +13 -0
- evol_cli/agent/hooks/scripts/stop-reme-summary.sh +36 -0
- evol_cli/agent/workflows/.gitkeep +0 -0
- evol_cli/agent/workflows/a11y-audit.md +56 -0
- evol_cli/agent/workflows/adr-new.md +52 -0
- evol_cli/agent/workflows/advanced-agentic-pentesting.md +60 -0
- evol_cli/agent/workflows/agent-factory.md +41 -0
- evol_cli/agent/workflows/analisis-impacto.md +117 -0
- evol_cli/agent/workflows/analyst.md +21 -0
- evol_cli/agent/workflows/analytics-instrument.md +57 -0
- evol_cli/agent/workflows/api-contract.md +56 -0
- evol_cli/agent/workflows/architect.md +22 -0
- evol_cli/agent/workflows/brainstorm.md +90 -0
- evol_cli/agent/workflows/builder.md +28 -0
- evol_cli/agent/workflows/ci-cd-setup.md +84 -0
- evol_cli/agent/workflows/cierre-fase.md +80 -0
- evol_cli/agent/workflows/clarify.md +94 -0
- evol_cli/agent/workflows/code-as-tool.md +95 -0
- evol_cli/agent/workflows/contract-test.md +51 -0
- evol_cli/agent/workflows/crear-skill.md +334 -0
- evol_cli/agent/workflows/cross-validate.md +81 -0
- evol_cli/agent/workflows/data-pipeline.md +58 -0
- evol_cli/agent/workflows/data.md +21 -0
- evol_cli/agent/workflows/db-migrate.md +62 -0
- evol_cli/agent/workflows/dependency-update.md +118 -0
- evol_cli/agent/workflows/deploy-prod.md +100 -0
- evol_cli/agent/workflows/design-system-builder.md +42 -0
- evol_cli/agent/workflows/devops.md +21 -0
- evol_cli/agent/workflows/doc.md +33 -0
- evol_cli/agent/workflows/domain.md +22 -0
- evol_cli/agent/workflows/dr-drill.md +57 -0
- evol_cli/agent/workflows/evol-profile.md +31 -0
- evol_cli/agent/workflows/evolve.md +87 -0
- evol_cli/agent/workflows/fase-requisitos.md +125 -0
- evol_cli/agent/workflows/feature-flag.md +57 -0
- evol_cli/agent/workflows/finops-baseline.md +53 -0
- evol_cli/agent/workflows/generar-flujo.md +85 -0
- evol_cli/agent/workflows/generate-unit-tests.md +79 -0
- evol_cli/agent/workflows/i18n-setup.md +62 -0
- evol_cli/agent/workflows/incidente-ID.md +128 -0
- evol_cli/agent/workflows/mejorar-prompt.md +84 -0
- evol_cli/agent/workflows/mempalace-sync.md +51 -0
- evol_cli/agent/workflows/ml-eval.md +63 -0
- evol_cli/agent/workflows/mobile-release.md +63 -0
- evol_cli/agent/workflows/observability-init.md +58 -0
- evol_cli/agent/workflows/onboard-dev.md +60 -0
- evol_cli/agent/workflows/orchestrate.md +52 -0
- evol_cli/agent/workflows/orchestrator.md +26 -0
- evol_cli/agent/workflows/perf-budget.md +62 -0
- evol_cli/agent/workflows/plan-fases.md +75 -0
- evol_cli/agent/workflows/pm.md +21 -0
- evol_cli/agent/workflows/privacy-review.md +63 -0
- evol_cli/agent/workflows/project-architecture-gsd.md +93 -0
- evol_cli/agent/workflows/pruebas-fuzz.md +117 -0
- evol_cli/agent/workflows/pruebas-humo.md +111 -0
- evol_cli/agent/workflows/qa-review.md +84 -0
- evol_cli/agent/workflows/qa.md +22 -0
- evol_cli/agent/workflows/refactor-area.md +80 -0
- evol_cli/agent/workflows/release-cut.md +58 -0
- evol_cli/agent/workflows/release.md +21 -0
- evol_cli/agent/workflows/research.md +62 -0
- evol_cli/agent/workflows/researcher.md +38 -0
- evol_cli/agent/workflows/reviewer.md +21 -0
- evol_cli/agent/workflows/rollback.md +121 -0
- evol_cli/agent/workflows/sec.md +21 -0
- evol_cli/agent/workflows/secure-isolation-ops.md +72 -0
- evol_cli/agent/workflows/security-audit.md +84 -0
- evol_cli/agent/workflows/skill-template-generator.md +84 -0
- evol_cli/agent/workflows/stress-test.md +77 -0
- evol_cli/agent/workflows/technical-documentation.md +86 -0
- evol_cli/agent/workflows/ux-discovery.md +52 -0
- evol_cli/agent/workflows/ux.md +22 -0
- evol_cli/docs/.gitkeep +0 -0
- evol_cli/docs/CONFIG.md +121 -0
- evol_cli/docs/DOC_STANDARD.md +51 -0
- evol_cli/docs/GATE.md +88 -0
- evol_cli/docs/IDE_SETUP.md +367 -0
- evol_cli/docs/README.md +37 -0
- evol_cli/docs/RETROFIT_GUIDE.md +224 -0
- evol_cli/docs/SECURITY_PERMISSIONS.md +68 -0
- evol_cli/docs/X-DD_Integration_Guide.md +121 -0
- evol_cli/docs/api/API_GUIDE.md +270 -0
- evol_cli/docs/api/openapi.yaml +5 -0
- evol_cli/docs/arquitectura/ARQUITECTURA.md +490 -0
- evol_cli/docs/arquitectura/DECISIONES.md +199 -0
- evol_cli/docs/arquitectura/DOMINIO.md +409 -0
- evol_cli/docs/arquitectura/adr/ADR-0001.md +14 -0
- evol_cli/docs/constitucion.md +155 -0
- evol_cli/docs/diagramas/componentes.md +159 -0
- evol_cli/docs/diagramas/despliegue.md +87 -0
- evol_cli/docs/diagramas/flujo-datos.md +145 -0
- evol_cli/docs/equipo.md +30 -0
- evol_cli/docs/gitnexus-optin.md +136 -0
- evol_cli/docs/guias/CONTRIBUCION.md +395 -0
- evol_cli/docs/guias/ONBOARDING.md +419 -0
- evol_cli/docs/guias/TROUBLESHOOTING.md +526 -0
- evol_cli/docs/modos.md +44 -0
- evol_cli/docs/operaciones/DR_PLAN.md +242 -0
- evol_cli/docs/operaciones/MONITORING.md +115 -0
- evol_cli/docs/operaciones/RELEASE_PROCESS.md +134 -0
- evol_cli/docs/operaciones/RUNBOOK.md +282 -0
- evol_cli/docs/operaciones/TAG_STRATEGY.md +62 -0
- evol_cli/docs/profiles/README.md +64 -0
- evol_cli/docs/qa/CASOS_BORDE.md +210 -0
- evol_cli/docs/qa/CASOS_GHERKIN.md +666 -0
- evol_cli/docs/qa/CHECKLIST_RELEASE.md +144 -0
- evol_cli/docs/qa/MATRIZ_TRAZABILIDAD.md +84 -0
- evol_cli/docs/qa/PLAN_QA.md +529 -0
- evol_cli/docs/qa/REPORTE_QA.md +138 -0
- evol_cli/docs/requisitos/FUNCIONALES.md +400 -0
- evol_cli/docs/requisitos/GLOSARIO.md +449 -0
- evol_cli/docs/requisitos/NO_FUNCIONALES.md +487 -0
- evol_cli/docs/requisitos/RESTRICCIONES.md +234 -0
- evol_cli/docs/seguridad/PRIVACY.md +85 -0
- evol_cli/docs/seguridad/SECURITY_CONTROLS.md +55 -0
- evol_cli/docs/seguridad/THREATS.md +159 -0
- evol_cli/docs/usuario/FAQ.md +7 -0
- evol_cli/docs/usuario/MANUAL_USUARIO.md +241 -0
- evol_cli/manifests/install-components.json +3 -0
- evol_cli/manifests/install-modules.json +166 -0
- evol_cli/manifests/install-profiles.json +81 -0
- evol_cli/scripts/_evol_common.py +138 -0
- evol_cli/scripts/_generate_equipo.py +35 -0
- evol_cli/scripts/bump-version.py +30 -0
- evol_cli/scripts/evol-adapt.sh +211 -0
- evol_cli/scripts/evol-agent-lifecycle.py +318 -0
- evol_cli/scripts/evol-brand.sh +93 -0
- evol_cli/scripts/evol-doctor.sh +421 -0
- evol_cli/scripts/evol-eval.py +540 -0
- evol_cli/scripts/evol-evolve.py +471 -0
- evol_cli/scripts/evol-flow.py +53 -0
- evol_cli/scripts/evol-gate.py +244 -0
- evol_cli/scripts/evol-global-install.sh +143 -0
- evol_cli/scripts/evol-init.sh +315 -0
- evol_cli/scripts/evol-lessons.py +449 -0
- evol_cli/scripts/evol-memory.py +205 -0
- evol_cli/scripts/evol-orchestrate.py +8 -0
- evol_cli/scripts/evol-profile.py +316 -0
- evol_cli/scripts/evol-provider.py +67 -0
- evol_cli/scripts/evol-researcher.py +184 -0
- evol_cli/scripts/evol-shield.py +271 -0
- evol_cli/scripts/evol-start.sh +21 -0
- evol_cli/scripts/evol-state.py +226 -0
- evol_cli/scripts/evol-update.py +236 -0
- evol_cli/scripts/generate-equipo.sh +20 -0
- evol_cli/scripts/lint-workflows.sh +31 -0
- evol_cli/scripts/validate-registry.py +116 -0
- evol_cli/skills/agent-eval/.gitkeep +0 -0
- evol_cli/skills/agent-eval/SKILL.md +50 -0
- evol_cli/skills/crear-agente/SKILL.md +190 -0
- evol_cli/skills/crear-agente/evals/evals.json +82 -0
- evol_cli/skills/crear-agente/evals/trigger_evals.json +22 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-1-legal-saas/baseline/agent.md +382 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-1-legal-saas/with_skill/specialized-legal-saas-reviewer.md +90 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-2-a11y-efimero/baseline/agent.md +147 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-2-a11y-efimero/with_skill/2026-06-02-wcag-auditor.md +126 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-3-data-engineer/baseline/agent.md +455 -0
- evol_cli/skills/crear-agente/evals/workspace/iter-1/eval-3-data-engineer/with_skill/engineering-data-engineer-ecommerce.md +121 -0
- evol_cli/skills/crear-agente/references/agent-template-spec.md +80 -0
- evol_cli/skills/crear-agente/references/categorias.md +32 -0
- evol_cli/skills/crear-agente/references/ejemplos.md +76 -0
- evol_cli/skills/crear-agente/scripts/validate_agent.py +98 -0
- evol_cli/skills/crear-skill/SKILL.md +122 -0
- evol_cli/skills/evol-ai-review/.gitkeep +0 -0
- evol_cli/skills/evol-ai-review/SKILL.md +37 -0
- evol_cli/skills/evol-compact/.gitkeep +0 -0
- evol_cli/skills/evol-compact/SKILL.md +33 -0
- evol_cli/skills/evol-fs-context/.gitkeep +0 -0
- evol_cli/skills/evol-fs-context/SKILL.md +32 -0
- evol_cli/skills/evol-sandbox/.gitkeep +0 -0
- evol_cli/skills/evol-sandbox/SKILL.md +40 -0
- evol_cli/skills/evol-skill-manager/.gitkeep +0 -0
- evol_cli/skills/evol-skill-manager/SKILL.md +47 -0
- evol_cli/skills/evol-talk-compact/.gitkeep +0 -0
- evol_cli/skills/evol-talk-compact/SKILL.md +31 -0
- evol_cli/templates/AGENT_MEMORY.template.md +26 -0
- evol_cli/templates/agent.template.md +51 -0
- evol_cli/templates/evol-dd.PROMPT.template.md +1611 -0
- evol_cli/templates/gitignore.template +80 -0
- evol_cli/templates/lecciones.template.md +34 -0
- evol_cli/templates/memoria.template.md +63 -0
- evol_cli/templates/working-context.template.md +9 -0
- evol_dd-0.1.0.dist-info/METADATA +199 -0
- evol_dd-0.1.0.dist-info/RECORD +202 -0
- evol_dd-0.1.0.dist-info/WHEEL +4 -0
- evol_dd-0.1.0.dist-info/entry_points.txt +14 -0
- evol_dd-0.1.0.dist-info/licenses/LICENSE +21 -0
evol_cli/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
evol_cli/__init__.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""evol_cli — Entry-point dispatcher para Evol-DD.
|
|
2
|
+
|
|
3
|
+
NO reescribe los scripts (patron ADR-0008 de X-DD: consolidacion CLI diferida).
|
|
4
|
+
Cada entry-point es un dispatcher fino que ejecuta el script correspondiente.
|
|
5
|
+
|
|
6
|
+
Resolucion de paths (mismo patron que xdd_cli — fix aprendido de X-DD):
|
|
7
|
+
1. EVOL_SCRIPTS_DIR / EVOL_DATA_DIR si estan seteados.
|
|
8
|
+
2. Instalacion editable: directorio junto al repo (../../scripts desde src/evol_cli).
|
|
9
|
+
3. Data del wheel: directorio empaquetado dentro del paquete (evol_cli/<dir>).
|
|
10
|
+
|
|
11
|
+
Bug historico corregido preventivamente: pyproject.toml empaqueta TODOS los
|
|
12
|
+
data dirs (manifests/, templates/, .agent/, skills/, docs/, VERSION) para que
|
|
13
|
+
evol --version y evol init --list-profiles funcionen en instalacion pipx/wheel.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import runpy
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _resolve_version() -> str:
|
|
25
|
+
try:
|
|
26
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
27
|
+
return version("evol-dd")
|
|
28
|
+
except (ImportError, Exception):
|
|
29
|
+
pass
|
|
30
|
+
# Fallback: leer VERSION desde data dir
|
|
31
|
+
try:
|
|
32
|
+
return (_data_dir() / "VERSION").read_text(encoding="utf-8").strip()
|
|
33
|
+
except Exception:
|
|
34
|
+
return "0.1.0-dev"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _scripts_dir() -> Path:
|
|
38
|
+
"""Resuelve el directorio scripts/ con logica de 3 niveles."""
|
|
39
|
+
env = os.environ.get("EVOL_SCRIPTS_DIR")
|
|
40
|
+
if env:
|
|
41
|
+
return Path(env)
|
|
42
|
+
here = Path(__file__).resolve().parent
|
|
43
|
+
# editable: repo_root/src/evol_cli → repo_root/scripts
|
|
44
|
+
repo_scripts = here.parent.parent / "scripts"
|
|
45
|
+
if repo_scripts.is_dir():
|
|
46
|
+
return repo_scripts
|
|
47
|
+
# wheel: scripts empaquetado como data dentro del paquete
|
|
48
|
+
bundled = here / "scripts"
|
|
49
|
+
if bundled.is_dir():
|
|
50
|
+
return bundled
|
|
51
|
+
raise FileNotFoundError(
|
|
52
|
+
"No encuentro scripts/ Evol-DD. Setea EVOL_SCRIPTS_DIR al directorio scripts/."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _data_dir() -> Path:
|
|
57
|
+
"""Raiz de los data dirs (manifests/, templates/, .agent/, skills/, docs/, VERSION).
|
|
58
|
+
|
|
59
|
+
Misma logica de 3 niveles que _scripts_dir().
|
|
60
|
+
Los scripts bash reciben esta ruta como EVOL_DATA_DIR para no depender de
|
|
61
|
+
dirname(BASH_SOURCE) relativo, que rompe en instalaciones pipx/wheel.
|
|
62
|
+
"""
|
|
63
|
+
env = os.environ.get("EVOL_DATA_DIR")
|
|
64
|
+
if env:
|
|
65
|
+
return Path(env)
|
|
66
|
+
here = Path(__file__).resolve().parent
|
|
67
|
+
# editable: repo_root/src/evol_cli → repo_root/
|
|
68
|
+
repo_root = here.parent.parent
|
|
69
|
+
if (repo_root / "manifests").is_dir():
|
|
70
|
+
return repo_root
|
|
71
|
+
# wheel: data empaquetado dentro del paquete (evol_cli/ contiene manifests/, etc.)
|
|
72
|
+
if (here / "manifests").is_dir():
|
|
73
|
+
return here
|
|
74
|
+
return here
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
__version__ = _resolve_version()
|
|
78
|
+
|
|
79
|
+
SCRIPTS = {
|
|
80
|
+
"gate": "evol-gate.py",
|
|
81
|
+
"eval": "evol-eval.py",
|
|
82
|
+
"flow": "evol-flow.py",
|
|
83
|
+
"provider": "evol-provider.py",
|
|
84
|
+
"shield": "evol-shield.py",
|
|
85
|
+
"orchestrate": "evol-orchestrate.py",
|
|
86
|
+
"agent": "evol-agent-lifecycle.py",
|
|
87
|
+
"evolve": "evol-evolve.py",
|
|
88
|
+
"research": "evol-researcher.py",
|
|
89
|
+
"memory": "evol-memory.py",
|
|
90
|
+
"lessons": "evol-lessons.py",
|
|
91
|
+
"update": "evol-update.py",
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
SHELL_SCRIPTS = {
|
|
95
|
+
"init": "evol-init.sh",
|
|
96
|
+
"start": "evol-start.sh",
|
|
97
|
+
"adapt": "evol-adapt.sh",
|
|
98
|
+
"doctor": "evol-doctor.sh",
|
|
99
|
+
"brand": "evol-brand.sh",
|
|
100
|
+
"global-install": "evol-global-install.sh",
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _run(script_name: str) -> int:
|
|
105
|
+
script = _scripts_dir() / script_name
|
|
106
|
+
if not script.exists():
|
|
107
|
+
print(f"[evol] script no encontrado: {script}", file=sys.stderr)
|
|
108
|
+
return 2
|
|
109
|
+
sys.argv = [str(script)] + sys.argv[1:]
|
|
110
|
+
try:
|
|
111
|
+
runpy.run_path(str(script), run_name="__main__")
|
|
112
|
+
except SystemExit as e:
|
|
113
|
+
return int(e.code) if isinstance(e.code, int) else (0 if e.code is None else 1)
|
|
114
|
+
return 0
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _run_shell(script_name: str, args: list[str]) -> int:
|
|
118
|
+
"""Ejecuta un script .sh con bash, inyectando EVOL_DATA_DIR."""
|
|
119
|
+
script = _scripts_dir() / script_name
|
|
120
|
+
if not script.exists():
|
|
121
|
+
print(f"[evol] script no encontrado: {script}", file=sys.stderr)
|
|
122
|
+
return 2
|
|
123
|
+
env = os.environ.copy()
|
|
124
|
+
env.setdefault("EVOL_DATA_DIR", str(_data_dir()))
|
|
125
|
+
return subprocess.call(["bash", str(script), *args], env=env)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _usage() -> None:
|
|
129
|
+
print(f"evol {__version__} — Evol-DD CLI")
|
|
130
|
+
print("\nComandos Python:")
|
|
131
|
+
for name in sorted(SCRIPTS):
|
|
132
|
+
print(f" {name}")
|
|
133
|
+
print("\nComandos Bash:")
|
|
134
|
+
for name in sorted(SHELL_SCRIPTS):
|
|
135
|
+
print(f" {name}")
|
|
136
|
+
print("\nEj: evol gate status · evol init /mi-proyecto · evol doctor")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def main(argv: list[str] | None = None) -> int:
|
|
140
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
141
|
+
if not argv or argv[0] in ("-h", "--help"):
|
|
142
|
+
_usage()
|
|
143
|
+
return 0
|
|
144
|
+
if argv[0] in ("-v", "--version"):
|
|
145
|
+
print(f"evol-dd {__version__}")
|
|
146
|
+
return 0
|
|
147
|
+
sub, rest = argv[0], argv[1:]
|
|
148
|
+
if sub in SCRIPTS:
|
|
149
|
+
sys.argv = [SCRIPTS[sub]] + rest
|
|
150
|
+
return _run(SCRIPTS[sub])
|
|
151
|
+
if sub in SHELL_SCRIPTS:
|
|
152
|
+
return _run_shell(SHELL_SCRIPTS[sub], rest)
|
|
153
|
+
print(f"[evol] subcomando desconocido: {sub!r}", file=sys.stderr)
|
|
154
|
+
_usage()
|
|
155
|
+
return 2
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# Entry-points individuales
|
|
159
|
+
def gate(): sys.argv = ["evol-gate"] + sys.argv[2:]; _run(SCRIPTS["gate"])
|
|
160
|
+
def eval_(): sys.argv = ["evol-eval"] + sys.argv[2:]; _run(SCRIPTS["eval"])
|
|
161
|
+
def flow(): sys.argv = ["evol-flow"] + sys.argv[2:]; _run(SCRIPTS["flow"])
|
|
162
|
+
def provider(): sys.argv = ["evol-provider"] + sys.argv[2:]; _run(SCRIPTS["provider"])
|
|
163
|
+
def shield(): sys.argv = ["evol-shield"] + sys.argv[2:]; _run(SCRIPTS["shield"])
|
|
164
|
+
def orchestrate(): sys.argv = ["evol-orchestrate"] + sys.argv[2:]; _run(SCRIPTS["orchestrate"])
|
|
165
|
+
def agent(): sys.argv = ["evol-agent"] + sys.argv[2:]; _run(SCRIPTS["agent"])
|
|
166
|
+
def evolve(): sys.argv = ["evol-evolve"] + sys.argv[2:]; _run(SCRIPTS["evolve"])
|
|
167
|
+
def research(): sys.argv = ["evol-research"] + sys.argv[2:]; _run(SCRIPTS["research"])
|
|
168
|
+
def memory(): sys.argv = ["evol-memory"] + sys.argv[2:]; _run(SCRIPTS["memory"])
|
|
169
|
+
def lessons(): sys.argv = ["evol-lessons"] + sys.argv[2:]; _run(SCRIPTS["lessons"])
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
sys.exit(main())
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0",
|
|
3
|
+
"profiles": {
|
|
4
|
+
"minimal": [
|
|
5
|
+
{
|
|
6
|
+
"id": "post:edit:mempalace-index",
|
|
7
|
+
"event": "PostToolUse",
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"script": "post-edit-mempalace-index.sh",
|
|
10
|
+
"trigger": "edit"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"standard": [
|
|
14
|
+
{
|
|
15
|
+
"id": "pre:bash:dangerous-command",
|
|
16
|
+
"event": "PreToolUse",
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"script": "pre-bash-dangerous-command.sh",
|
|
19
|
+
"trigger": "bash"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "pre:write:doc-file-warning",
|
|
23
|
+
"event": "PreToolUse",
|
|
24
|
+
"enabled": true,
|
|
25
|
+
"script": "pre-write-doc-file-warning.sh",
|
|
26
|
+
"trigger": "write"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "post:bash:pr-logger",
|
|
30
|
+
"event": "PostToolUse",
|
|
31
|
+
"enabled": true,
|
|
32
|
+
"script": "post-bash-pr-logger.sh",
|
|
33
|
+
"trigger": "bash"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "post:write:auto-organize",
|
|
37
|
+
"event": "PostToolUse",
|
|
38
|
+
"enabled": true,
|
|
39
|
+
"script": "post-write-auto-organize.sh",
|
|
40
|
+
"trigger": "write"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "session:start:context-load",
|
|
44
|
+
"event": "SessionStart",
|
|
45
|
+
"enabled": true,
|
|
46
|
+
"script": "session-start-context-load.sh"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "stop:git-check",
|
|
50
|
+
"event": "Stop",
|
|
51
|
+
"enabled": true,
|
|
52
|
+
"script": "stop-git-check.sh"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"strict": [
|
|
56
|
+
{
|
|
57
|
+
"id": "pre:edit:config-protection",
|
|
58
|
+
"event": "PreToolUse",
|
|
59
|
+
"enabled": true,
|
|
60
|
+
"script": "pre-edit-config-protection.sh",
|
|
61
|
+
"trigger": "edit"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "pre:tool:temporal-awareness",
|
|
65
|
+
"event": "PreToolUse",
|
|
66
|
+
"enabled": true,
|
|
67
|
+
"script": "pre-tool-temporal-awareness.sh"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "stop:pattern-extraction",
|
|
71
|
+
"event": "Stop",
|
|
72
|
+
"enabled": true,
|
|
73
|
+
"script": "stop-pattern-extraction.sh"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
"default_profile": "standard"
|
|
78
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse hook: Log PR URL after gh pr create
|
|
3
|
+
|
|
4
|
+
OUTPUT="$1"
|
|
5
|
+
if echo "$OUTPUT" | grep -q "github.com.*pull/"; then
|
|
6
|
+
URL=$(echo "$OUTPUT" | grep -oE "https://github.com/[^ ]+/pull/[0-9]+" | head -1)
|
|
7
|
+
echo "[HOOK] PR Created: $URL"
|
|
8
|
+
fi
|
|
9
|
+
exit 0
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse hook: Move docs to canonical paths
|
|
3
|
+
|
|
4
|
+
DEST="$1"
|
|
5
|
+
if [ -f "$DEST" ]; then
|
|
6
|
+
case "$DEST" in
|
|
7
|
+
*architecture*.md) [ ! -d "docs/arquitectura" ] && mkdir -p "docs/arquitectura" ;;
|
|
8
|
+
*requisitos*.md) [ ! -d "docs/requisitos" ] && mkdir -p "docs/requisitos" ;;
|
|
9
|
+
*qa*.md|*test*.md) [ ! -d "docs/qa" ] && mkdir -p "docs/qa" ;;
|
|
10
|
+
*seguridad*.md|*security*.md) [ ! -d "docs/seguridad" ] && mkdir -p "docs/seguridad" ;;
|
|
11
|
+
esac
|
|
12
|
+
fi
|
|
13
|
+
exit 0
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block dangerous commands
|
|
3
|
+
# Exit 0 = allow, Exit 2 = block
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
COMMAND="$INPUT"
|
|
9
|
+
|
|
10
|
+
# Try parse JSON if available (Claude Code passes structured input)
|
|
11
|
+
if echo "$INPUT" | grep -q '^{'; then
|
|
12
|
+
COMMAND=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command','') or d.get('prompt','') or '')" 2>/dev/null || echo "$INPUT")
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Logging without secrets
|
|
16
|
+
log_blocked() {
|
|
17
|
+
local reason="$1"
|
|
18
|
+
local hook_log="${HOOK_LOG:-.agent/hooks/.hook-blocked.log}"
|
|
19
|
+
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BLOCKED: $reason" >> "$hook_log" 2>/dev/null || true
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
BLOCKED=0
|
|
23
|
+
|
|
24
|
+
# Block: rm -rf on root
|
|
25
|
+
if echo "$COMMAND" | grep -qE 'rm[[:space:]]+-rf[[:space:]]+/?$'; then
|
|
26
|
+
echo "[evol-hook] BLOQUEADO: rm -rf /" >&2
|
|
27
|
+
log_blocked "rm -rf /"
|
|
28
|
+
BLOCKED=1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Block: rm -rf on home directory
|
|
32
|
+
if echo "$COMMAND" | grep -qE 'rm[[:space:]]+-rf[[:space:]]+~'; then
|
|
33
|
+
echo "[evol-hook] BLOQUEADO: rm -rf ~" >&2
|
|
34
|
+
log_blocked "rm -rf ~"
|
|
35
|
+
BLOCKED=1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Block: rm -rf on protected system directories
|
|
39
|
+
if echo "$COMMAND" | grep -qE 'rm[[:space:]]+-rf[[:space:]]+(--[[:space:]]+)?/(etc|usr|bin|sbin|lib|boot|root|var|opt|dev|sys)'; then
|
|
40
|
+
echo "[evol-hook] BLOQUEADO: rm -rf sobre directorio de sistema" >&2
|
|
41
|
+
log_blocked "rm -rf /etc|/usr|/bin|..."
|
|
42
|
+
BLOCKED=1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Block: dd if= (disk dump)
|
|
46
|
+
if echo "$COMMAND" | grep -qE 'dd[[:space:]]+if='; then
|
|
47
|
+
echo "[evol-hook] BLOQUEADO: dd if= (operacion de disco cruda)" >&2
|
|
48
|
+
log_blocked "dd if="
|
|
49
|
+
BLOCKED=1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Block: mkfs (filesystem creation)
|
|
53
|
+
if echo "$COMMAND" | grep -qE 'mkfs'; then
|
|
54
|
+
echo "[evol-hook] BLOQUEADO: mkfs (creacion de filesystem)" >&2
|
|
55
|
+
log_blocked "mkfs"
|
|
56
|
+
BLOCKED=1
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Block: chmod -R 777
|
|
60
|
+
if echo "$COMMAND" | grep -qE 'chmod[[:space:]]+(-R[[:space:]]+|-R )?777'; then
|
|
61
|
+
echo "[evol-hook] BLOQUEADO: chmod 777 o chmod -R 777" >&2
|
|
62
|
+
log_blocked "chmod 777"
|
|
63
|
+
BLOCKED=1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Block: curl | sh / wget | sh
|
|
67
|
+
if echo "$COMMAND" | grep -qE '(curl|wget)[[:space:]].*[|][[:space:]]*(ba)?sh'; then
|
|
68
|
+
echo "[evol-hook] BLOQUEADO: curl/wget pipe a shell" >&2
|
|
69
|
+
log_blocked "curl|wget | sh"
|
|
70
|
+
BLOCKED=1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Block: bash <(curl ...)
|
|
74
|
+
if echo "$COMMAND" | grep -qE 'bash[[:space:]]*<[[:space:]]*\((curl|wget)'; then
|
|
75
|
+
echo "[evol-hook] BLOQUEADO: process substitution con curl/wget" >&2
|
|
76
|
+
log_blocked "bash <(curl...)"
|
|
77
|
+
BLOCKED=1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Block: sudo without authorized context
|
|
81
|
+
if echo "$COMMAND" | grep -qE '^sudo[[:space:]]' && [ -z "${EVOL_SUDO_AUTHORIZED:-}" ]; then
|
|
82
|
+
echo "[evol-hook] BLOQUEADO: sudo sin autorizacion explicita (EVOL_SUDO_AUTHORIZED no esta definido)" >&2
|
|
83
|
+
log_blocked "sudo without EVOL_SUDO_AUTHORIZED"
|
|
84
|
+
BLOCKED=1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Block: git push --force / --force-with-lease to protected branches
|
|
88
|
+
PROTECTED_BRANCHES="main|master|develop"
|
|
89
|
+
if echo "$COMMAND" | grep -qE "git[[:space:]]+push[[:space:]].*(--force-with-lease|--force-with-lease=.*)[[:space:]].*($PROTECTED_BRANCHES)"; then
|
|
90
|
+
echo "[evol-hook] BLOQUEADO: git push --force-with-lease a rama protegida" >&2
|
|
91
|
+
log_blocked "git push --force-with-lease"
|
|
92
|
+
BLOCKED=1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
if echo "$COMMAND" | grep -qE "git[[:space:]]+push[[:space:]].*(-f|--force)[[:space:]].*($PROTECTED_BRANCHES)"; then
|
|
96
|
+
echo "[evol-hook] BLOQUEADO: git push --force a rama protegida" >&2
|
|
97
|
+
log_blocked "git push --force"
|
|
98
|
+
BLOCKED=1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ "$BLOCKED" -eq 1 ]; then
|
|
102
|
+
exit 2
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
exit 0
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Pre-commit hook: Enforce GitFlow branch naming
|
|
3
|
+
|
|
4
|
+
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
|
|
5
|
+
|
|
6
|
+
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "develop" ]; then
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
ALLOWED='^(feature/|fix/|hotfix/|release/|chore/|docs/|refactor/)'
|
|
11
|
+
if ! [[ "$BRANCH" =~ $ALLOWED ]]; then
|
|
12
|
+
echo "[HOOK] BLOCKED: Branch '$BRANCH' does not follow GitFlow convention"
|
|
13
|
+
echo "[HOOK] Allowed: feature/*, fix/*, hotfix/*, release/*, chore/*, docs/*, refactor/*"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check conventional commits
|
|
18
|
+
if [ -f ".git/COMMIT_EDITMSG" ]; then
|
|
19
|
+
MSG=$(head -1 .git/COMMIT_EDITMSG)
|
|
20
|
+
if ! [[ "$MSG" =~ ^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert) ]]; then
|
|
21
|
+
echo "[HOOK] WARN: Commit message should follow Conventional Commits"
|
|
22
|
+
fi
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
exit 0
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block governance file edits without evol-gate approval
|
|
3
|
+
# Exit 0 = allow, Exit 2 = block
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
HOOK_LOG="${HOOK_LOG:-.agent/hooks/.hook-blocked.log}"
|
|
8
|
+
GATE_LOG=".evol/.gate-log.jsonl"
|
|
9
|
+
|
|
10
|
+
log_blocked() {
|
|
11
|
+
local reason="$1"
|
|
12
|
+
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BLOCKED: $reason" >> "$HOOK_LOG" 2>/dev/null || true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
PROTECTED_FILES="constitucion.md gates.md hooks.json .gate-key .gate-log.jsonl"
|
|
16
|
+
PROTECTED_PATTERNS="constitucion.md gates.md hooks.json"
|
|
17
|
+
|
|
18
|
+
# Check if evol-gate approve was run recently (within 1 hour)
|
|
19
|
+
check_gate_approval() {
|
|
20
|
+
if [ ! -f "$GATE_LOG" ]; then
|
|
21
|
+
return 1
|
|
22
|
+
fi
|
|
23
|
+
local last_approve
|
|
24
|
+
last_approve=$(grep -c '"phase"' "$GATE_LOG" 2>/dev/null || echo "0")
|
|
25
|
+
if [ "$last_approve" -gt 0 ]; then
|
|
26
|
+
return 0
|
|
27
|
+
fi
|
|
28
|
+
return 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
GATE_APPROVED=0
|
|
32
|
+
if check_gate_approval; then
|
|
33
|
+
GATE_APPROVED=1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
BLOCKED=0
|
|
37
|
+
for pattern in $PROTECTED_PATTERNS; do
|
|
38
|
+
if [[ "$1" == *"$pattern"* ]]; then
|
|
39
|
+
if [ "$GATE_APPROVED" -eq 1 ]; then
|
|
40
|
+
echo "[evol-hook] WARN: editing governance file: $pattern (gate approved)" >&2
|
|
41
|
+
else
|
|
42
|
+
echo "[evol-hook] BLOQUEADO: edicion de archivo de gobernanza '$pattern' requiere evol-gate approve" >&2
|
|
43
|
+
log_blocked "governance-edit:$pattern without gate"
|
|
44
|
+
BLOCKED=1
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
if [ "$BLOCKED" -eq 1 ]; then
|
|
50
|
+
exit 2
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Warn if doc file outside canonical paths
|
|
3
|
+
|
|
4
|
+
DEST="$1"
|
|
5
|
+
CANONICAL_DOCS="docs/ .claude/ .opencode/ AGENTS.md CLAUDE.md memoria.md"
|
|
6
|
+
|
|
7
|
+
if [[ "$DEST" =~ \.md$ ]]; then
|
|
8
|
+
IN_CANONICAL=false
|
|
9
|
+
for path in $CANONICAL_DOCS; do
|
|
10
|
+
if [[ "$DEST" == "$path"* ]]; then
|
|
11
|
+
IN_CANONICAL=true
|
|
12
|
+
break
|
|
13
|
+
fi
|
|
14
|
+
done
|
|
15
|
+
if [ "$IN_CANONICAL" = false ]; then
|
|
16
|
+
echo "[HOOK] WARN: Writing .md outside canonical paths: $DEST"
|
|
17
|
+
fi
|
|
18
|
+
fi
|
|
19
|
+
exit 0
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart hook: Load memoria.md and WORKING-CONTEXT
|
|
3
|
+
|
|
4
|
+
echo "=== Working Context ==="
|
|
5
|
+
|
|
6
|
+
if [ -f "memoria.md" ]; then
|
|
7
|
+
echo "--- memoria.md ---"
|
|
8
|
+
head -30 memoria.md
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
if [ -f "WORKING-CONTEXT.md" ]; then
|
|
12
|
+
echo "--- WORKING-CONTEXT.md ---"
|
|
13
|
+
cat WORKING-CONTEXT.md
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
echo "==================="
|
|
17
|
+
exit 0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Hook: session:start:reme-load — carga MEMORY.md + journal anterior via evol-memory.py nativo.
|
|
3
|
+
# Perfil: minimal+. Requiere EVOL_MEMORY=1. Sin dependencias externas.
|
|
4
|
+
# No-op si EVOL_MEMORY != 1. Exit 0 siempre.
|
|
5
|
+
set -eu
|
|
6
|
+
|
|
7
|
+
if [ "${EVOL_MEMORY:-0}" != "1" ]; then
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
SCRIPTS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/../../.." && pwd )/scripts"
|
|
12
|
+
PROJECT_DIR="${PWD}"
|
|
13
|
+
|
|
14
|
+
if [ ! -f "$SCRIPTS_DIR/evol-memory.py" ]; then
|
|
15
|
+
echo "[evol-memory] WARN: evol-memory.py no encontrado en $SCRIPTS_DIR" >&2
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
python3 "$SCRIPTS_DIR/evol-memory.py" --project "$PROJECT_DIR" load
|
|
20
|
+
exit 0
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop hook: Warn if uncommitted changes
|
|
3
|
+
|
|
4
|
+
if [ -d ".git" ]; then
|
|
5
|
+
UNCOMMITTED=$(git status --porcelain 2>/dev/null | wc -l)
|
|
6
|
+
if [ "$UNCOMMITTED" -gt 0 ]; then
|
|
7
|
+
echo "[HOOK] WARN: $UNCOMMITTED uncommitted changes"
|
|
8
|
+
echo "[HOOK] Run: git add . && git commit -m '...'"
|
|
9
|
+
fi
|
|
10
|
+
fi
|
|
11
|
+
exit 0
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Stop hook: Extract patterns for instincts
|
|
3
|
+
|
|
4
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
5
|
+
if [ -f "scripts/evol-state.py" ]; then
|
|
6
|
+
python3 scripts/evol-state.py record-instinct \
|
|
7
|
+
--pattern "session_pattern" \
|
|
8
|
+
--context "auto-extracted" \
|
|
9
|
+
--confidence 0.3 \
|
|
10
|
+
--source "stop-hook" 2>/dev/null || true
|
|
11
|
+
fi
|
|
12
|
+
fi
|
|
13
|
+
exit 0
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Hook: stop:reme-summary — persiste sesion en memory/YYYY-MM-DD.md via evol-memory.py nativo.
|
|
3
|
+
# Perfil: minimal+. Requiere EVOL_MEMORY=1. Sin dependencias externas.
|
|
4
|
+
# No-op si EVOL_MEMORY != 1. Exit 0 siempre (no bloquea cierre de sesion).
|
|
5
|
+
set -eu
|
|
6
|
+
|
|
7
|
+
if [ "${EVOL_MEMORY:-0}" != "1" ]; then
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
SCRIPTS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/../../.." && pwd )/scripts"
|
|
12
|
+
PROJECT_DIR="${PWD}"
|
|
13
|
+
|
|
14
|
+
if [ ! -f "$SCRIPTS_DIR/evol-memory.py" ]; then
|
|
15
|
+
echo "[evol-memory] WARN: evol-memory.py no encontrado" >&2
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# El evento Stop puede proveer JSON de mensajes via stdin — guardarlo en tmp
|
|
20
|
+
TMPFILE=$(mktemp /tmp/evol-memory-XXXXXX.jsonl 2>/dev/null || echo "")
|
|
21
|
+
if [ -n "$TMPFILE" ]; then
|
|
22
|
+
cat > "$TMPFILE" 2>/dev/null || true
|
|
23
|
+
if [ -s "$TMPFILE" ]; then
|
|
24
|
+
python3 "$SCRIPTS_DIR/evol-memory.py" --project "$PROJECT_DIR" summarize --messages "$TMPFILE" &
|
|
25
|
+
else
|
|
26
|
+
python3 "$SCRIPTS_DIR/evol-memory.py" --project "$PROJECT_DIR" summarize &
|
|
27
|
+
fi
|
|
28
|
+
rm -f "$TMPFILE"
|
|
29
|
+
else
|
|
30
|
+
python3 "$SCRIPTS_DIR/evol-memory.py" --project "$PROJECT_DIR" summarize &
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# gc de tool_result/ vencidos (async, en background)
|
|
34
|
+
python3 "$SCRIPTS_DIR/evol-memory.py" --project "$PROJECT_DIR" gc &
|
|
35
|
+
|
|
36
|
+
exit 0
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Auditoría de accesibilidad WCAG 2.1 AA. Automatizada en CI + revisión humana de flujos críticos.
|
|
3
|
+
name: a11y-audit
|
|
4
|
+
trigger: /evol a11y-audit
|
|
5
|
+
---
|
|
6
|
+
# /a11y-audit
|
|
7
|
+
|
|
8
|
+
> **Estandar de documentacion:** Todo artefacto que produzca este workflow cumple
|
|
9
|
+
> [`docs/DOC_STANDARD.md`](../../docs/DOC_STANDARD.md): sin emojis, diagramas Mermaid
|
|
10
|
+
> obligatorios, tablas para datos estructurados, Gherkin donde aplique, secciones
|
|
11
|
+
> minimas y trazabilidad bidireccional.
|
|
12
|
+
**ID:** FLUJO-A11Y | **Versión:** 1.0 | **Agente:** Frontend-Developer + Accessibility-Auditor
|
|
13
|
+
**Misión:** Producto usable para personas con discapacidad. WCAG 2.1 AA mínimo, AAA donde sea razonable.
|
|
14
|
+
|
|
15
|
+
## 0. Pre-flight
|
|
16
|
+
- Solo aplica si el producto tiene UI (web, mobile, desktop).
|
|
17
|
+
|
|
18
|
+
## 1. Cobertura automática (CI)
|
|
19
|
+
<!-- CONFIGURAR: Herramientas. -->
|
|
20
|
+
<!-- - Web: axe-core (Playwright/Cypress), Pa11y, Lighthouse a11y -->
|
|
21
|
+
<!-- - Mobile: Accessibility Scanner (Android), Accessibility Inspector (iOS) -->
|
|
22
|
+
<!-- - Design system: Storybook + axe addon -->
|
|
23
|
+
|
|
24
|
+
Tests automatizados verifican:
|
|
25
|
+
- Contraste de color (4.5:1 texto normal, 3:1 large)
|
|
26
|
+
- Roles ARIA correctos, no abusivos
|
|
27
|
+
- Labels en todos los form controls
|
|
28
|
+
- Foco visible y orden lógico
|
|
29
|
+
- Alternativas de texto en imágenes
|
|
30
|
+
|
|
31
|
+
## 2. Cobertura manual (no automatizable)
|
|
32
|
+
Revisión humana de flujos críticos (signup, checkout, settings):
|
|
33
|
+
- **Teclado**: navegación 100% con teclado, sin trampas de foco
|
|
34
|
+
- **Lector de pantalla**: VoiceOver (macOS/iOS) + NVDA (Windows) + TalkBack (Android)
|
|
35
|
+
- **Zoom 200%** sin pérdida de contenido ni scroll horizontal
|
|
36
|
+
- **Reduce motion**: respetar `prefers-reduced-motion`
|
|
37
|
+
- **Color**: información no solo por color (probar con simulador daltonismo)
|
|
38
|
+
|
|
39
|
+
## 3. Componentes
|
|
40
|
+
- Design system con componentes accesibles por construcción.
|
|
41
|
+
- Cada componente nuevo trae tests a11y antes de merge.
|
|
42
|
+
- Documentación de patrones (modales, menús, formularios) sigue ARIA Authoring Practices Guide.
|
|
43
|
+
|
|
44
|
+
## 4. Contenido
|
|
45
|
+
- Estructura semántica (h1-h6 correctos, landmarks).
|
|
46
|
+
- Idioma declarado (`<html lang>`) — cruzar con `/i18n-setup`.
|
|
47
|
+
- Vídeos con subtítulos, transcripciones de audio.
|
|
48
|
+
|
|
49
|
+
## 5. CI gate
|
|
50
|
+
- PR bloquea si violación nivel `serious` o `critical`.
|
|
51
|
+
- Violaciones `moderate` permitidas con justificación temporal y issue trackeado.
|
|
52
|
+
|
|
53
|
+
## 6. Cierre
|
|
54
|
+
- Reporte a `qa-review` Tier 2.
|
|
55
|
+
- Hallazgos críticos a `lecciones.md`.
|
|
56
|
+
- Roadmap de mejoras a11y mantenido (no "lo arreglamos cuando podamos").
|