@saulwade/swl-ses 1.2.2 → 1.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.
- package/CLAUDE.md +196 -255
- package/README.md +4 -4
- package/comandos/swl/claudemd.md +136 -0
- package/comandos/swl/salud.md +29 -0
- package/habilidades/nuevo-proyecto/SKILL.md +82 -2
- package/habilidades/swl-claudemd/SKILL.md +220 -0
- package/hooks/claudemd-bloat-detector.js +161 -0
- package/manifiestos/hooks-config.json +9 -0
- package/manifiestos/modulos.json +21 -2
- package/package.json +87 -87
- package/plugin.json +343 -343
- package/scripts/auditar-claudemd.js +297 -0
- package/scripts/instalador.js +4 -0
- package/scripts/lib/detectar-stack-detallado.js +307 -0
- package/scripts/lib/transformadores/claude.js +200 -124
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swl:claudemd
|
|
3
|
+
description: Audita, refactoriza, valida o inicializa archivos CLAUDE.md según best practices Anthropic (ADR-0016). Subcomandos audit (analiza calidad), refactor (sugiere extracciones), check (verifica secciones canónicas), init-user (crea ~/.claude/CLAUDE.md template), init-project (genera CLAUDE.md raíz del proyecto).
|
|
4
|
+
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /swl:claudemd — Tratamiento profesional de CLAUDE.md
|
|
8
|
+
|
|
9
|
+
Comando para auditar, refactorizar y mantener `CLAUDE.md` siguiendo las
|
|
10
|
+
cinco recomendaciones del video oficial Anthropic *"The CLAUDE.md file"*:
|
|
11
|
+
|
|
12
|
+
1. **Compacto** — empieza sin uno, agrega solo lo que tengas que corregir
|
|
13
|
+
2. **Stack arriba** — lenguaje, framework, ORM, BD
|
|
14
|
+
3. **Commands** — cómo correr dev, tests, lint, build
|
|
15
|
+
4. **Code style** — convenciones de indentación, exports, nombrado
|
|
16
|
+
5. **Conventions** — dónde van las cosas, qué patrones preferir
|
|
17
|
+
|
|
18
|
+
**Carga**: `Skill("swl-claudemd")` — contiene la lógica de auditoría, las
|
|
19
|
+
secciones canónicas, los umbrales de inflación y los templates de
|
|
20
|
+
generación. Delega análisis y criterios al skill.
|
|
21
|
+
|
|
22
|
+
## Subcomandos
|
|
23
|
+
|
|
24
|
+
| Subcomando | Propósito |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `/swl:claudemd audit` | Audita el CLAUDE.md actual (líneas, bullets gigantes, secciones canónicas, @references, placeholders) |
|
|
27
|
+
| `/swl:claudemd check` | Como audit pero exit 1 si hay WARN — útil en pre-commit/CI |
|
|
28
|
+
| `/swl:claudemd refactor` | Sugiere extracciones a archivos `@`-referenciados (no modifica, solo propone diff) |
|
|
29
|
+
| `/swl:claudemd init-user` | Crea `~/.claude/CLAUDE.md` con template de preferencias personales si no existe |
|
|
30
|
+
| `/swl:claudemd init-project` | Genera CLAUDE.md raíz del proyecto detectando el stack actual |
|
|
31
|
+
|
|
32
|
+
Sin subcomando: equivale a `audit`.
|
|
33
|
+
|
|
34
|
+
## Cuándo usar
|
|
35
|
+
|
|
36
|
+
- Después de modificar manualmente CLAUDE.md (verifica calidad)
|
|
37
|
+
- Al inicio de un proyecto que no tenía CLAUDE.md (init-project)
|
|
38
|
+
- Al cambiar de máquina y querer transportar preferencias (init-user)
|
|
39
|
+
- En pre-commit hook si el proyecto trackea CLAUDE.md (check)
|
|
40
|
+
- Cuando el hook `claudemd-bloat-detector` emite nudge
|
|
41
|
+
|
|
42
|
+
## Ejecución de cada subcomando
|
|
43
|
+
|
|
44
|
+
### audit / check
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node scripts/auditar-claudemd.js # output legible
|
|
48
|
+
node scripts/auditar-claudemd.js --json # output JSON estructurado
|
|
49
|
+
node scripts/auditar-claudemd.js --strict # exit 1 si WARN (modo check)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
El veredicto puede ser:
|
|
53
|
+
|
|
54
|
+
- **OK** — cumple best practices, sin hallazgos
|
|
55
|
+
- **WARN** — tiene oportunidades de mejora (líneas excesivas, bullets
|
|
56
|
+
gigantes, secciones ausentes, sin @references)
|
|
57
|
+
- **ERROR** — no existe, tiene placeholders sin reemplazar, faltan
|
|
58
|
+
secciones críticas
|
|
59
|
+
|
|
60
|
+
### refactor
|
|
61
|
+
|
|
62
|
+
Lee el CLAUDE.md actual, identifica candidatos a extracción (bullets
|
|
63
|
+
monolíticos, secciones largas, contenido duplicable a `@references`) y
|
|
64
|
+
imprime el diff propuesto. **NO modifica el archivo** — el usuario
|
|
65
|
+
revisa y aplica manualmente o con `git apply`.
|
|
66
|
+
|
|
67
|
+
Patrones de extracción típicos:
|
|
68
|
+
|
|
69
|
+
| Si el bullet/sección contiene… | Mover a… |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Variables de entorno opt-in | `docs/variables-entorno.md` |
|
|
72
|
+
| Reglas de gobernanza extensas | `docs/gobernanza.md` |
|
|
73
|
+
| Catálogo de comandos completo | `COMANDOS.md` (referenciar) |
|
|
74
|
+
| Mapa de propagación detallado | `docs/mapa-propagacion.md` |
|
|
75
|
+
| Convenciones de cada capa | `docs/convenciones-{capa}.md` |
|
|
76
|
+
|
|
77
|
+
### init-user
|
|
78
|
+
|
|
79
|
+
Verifica si existe `~/.claude/CLAUDE.md` (en Windows:
|
|
80
|
+
`%USERPROFILE%\.claude\CLAUDE.md`). Si no existe, genera template
|
|
81
|
+
mínimo:
|
|
82
|
+
|
|
83
|
+
```markdown
|
|
84
|
+
# CLAUDE.md (preferencias personales transversales)
|
|
85
|
+
|
|
86
|
+
> Este archivo aplica a TODOS mis proyectos. Las reglas específicas de
|
|
87
|
+
> proyecto van en el CLAUDE.md de la raíz del proyecto, no aquí.
|
|
88
|
+
|
|
89
|
+
## Mi rol y stack preferido
|
|
90
|
+
|
|
91
|
+
- Rol: [ej. ingeniero senior backend]
|
|
92
|
+
- Stack preferido: [ej. Python + FastAPI, TypeScript + Next.js]
|
|
93
|
+
- Herramientas habituales: [ej. Neovim, ripgrep, fd, gh CLI]
|
|
94
|
+
|
|
95
|
+
## Estilo de comunicación
|
|
96
|
+
|
|
97
|
+
- Idioma: español
|
|
98
|
+
- Formato preferido para respuestas: [breve / detallado / con tablas]
|
|
99
|
+
- Cuándo prefiero ver alternativas vs. una sola recomendación
|
|
100
|
+
|
|
101
|
+
## Patrones que aplico siempre
|
|
102
|
+
|
|
103
|
+
- [ej. "Antes de implementar, mostrar el plan"]
|
|
104
|
+
- [ej. "Tests para todo código nuevo, sin excepción"]
|
|
105
|
+
- [ej. "Commits atómicos en español, formato conventional"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Si ya existe, NO lo sobreescribe — sugiere añadir secciones faltantes.
|
|
109
|
+
|
|
110
|
+
### init-project
|
|
111
|
+
|
|
112
|
+
Detecta el stack del proyecto actual con `scripts/lib/detectar-stack-detallado.js`
|
|
113
|
+
y genera `./CLAUDE.md` mínimo con:
|
|
114
|
+
|
|
115
|
+
- Sección **Stack** poblada (lenguaje, framework, ORM, package manager)
|
|
116
|
+
- Sección **Comandos** poblada (npm scripts detectados o comandos típicos)
|
|
117
|
+
- Sección **Code style** vacía con placeholders
|
|
118
|
+
- Sección **Conventions** vacía con placeholders
|
|
119
|
+
- Sección **@references** apuntando a `.planning/PROYECTO.md`,
|
|
120
|
+
`README.md`, etc. si existen
|
|
121
|
+
|
|
122
|
+
Si CLAUDE.md ya existe, **NO lo sobreescribe**. Sugiere correr
|
|
123
|
+
`/swl:claudemd refactor` para mejorar el actual.
|
|
124
|
+
|
|
125
|
+
## Variables de entorno
|
|
126
|
+
|
|
127
|
+
Ver `@docs/variables-entorno.md` sección "Calidad de CLAUDE.md":
|
|
128
|
+
|
|
129
|
+
- `SWL_CLAUDEMD_BLOAT` (on/off) — activa hook `claudemd-bloat-detector`
|
|
130
|
+
- `SWL_CLAUDEMD_MAX_LINES` (default 200) — umbral de líneas totales
|
|
131
|
+
- `SWL_CLAUDEMD_MAX_BULLET_CHARS` (default 1000) — umbral de bullet/párrafo
|
|
132
|
+
|
|
133
|
+
## Exit codes
|
|
134
|
+
|
|
135
|
+
- `0` — OK o WARN (consultivo)
|
|
136
|
+
- `1` — ERROR o `--strict` + WARN
|
package/comandos/swl/salud.md
CHANGED
|
@@ -286,6 +286,35 @@ Si `SWL_AUDIT_AGENTES` no está definida, este paso se omite — los reportes
|
|
|
286
286
|
son opt-in por diseño (CLAUDE.md: "Variables de entorno opt-in para
|
|
287
287
|
integraciones enterprise").
|
|
288
288
|
|
|
289
|
+
## Paso 5f — Calidad de CLAUDE.md (ADR-0016)
|
|
290
|
+
|
|
291
|
+
Auditoría determinista del archivo `CLAUDE.md` raíz del proyecto según best
|
|
292
|
+
practices Anthropic ("The CLAUDE.md file"): líneas totales, bullets
|
|
293
|
+
monolíticos, secciones canónicas (Stack/Comandos/Code style/Conventions),
|
|
294
|
+
uso de `@references`, placeholders sin reemplazar.
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
node scripts/auditar-claudemd.js --json
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Veredictos posibles:
|
|
301
|
+
|
|
302
|
+
| Veredicto | Significado | Score impact |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| `OK` | Cumple best practices, sin hallazgos | +1 |
|
|
305
|
+
| `WARN` | Oportunidades de mejora (líneas excesivas, bullets gigantes, secciones ausentes, sin @references) | -0.5 |
|
|
306
|
+
| `ERROR` | No existe, placeholders sin reemplazar, secciones críticas ausentes | -1 |
|
|
307
|
+
|
|
308
|
+
Si veredicto != OK, el reporte sugiere ejecutar `/swl:claudemd refactor`
|
|
309
|
+
para identificar candidatos a extracción a archivos `@`-referenciados.
|
|
310
|
+
|
|
311
|
+
Variables de entorno: `SWL_CLAUDEMD_MAX_LINES` (default 200) y
|
|
312
|
+
`SWL_CLAUDEMD_MAX_BULLET_CHARS` (default 1000) ajustan los umbrales.
|
|
313
|
+
Documentación completa en `@docs/variables-entorno.md`.
|
|
314
|
+
|
|
315
|
+
Este paso siempre se ejecuta (no es opt-in) — la calidad de CLAUDE.md
|
|
316
|
+
es métrica continua del sistema.
|
|
317
|
+
|
|
289
318
|
## Paso 5e — Verificación de drift de skills (skills-lock)
|
|
290
319
|
|
|
291
320
|
Si existe `manifiestos/skills-lock.json`, comparar el hash actual de cada
|
|
@@ -176,7 +176,85 @@ Una vez obtenidas las respuestas, crea la carpeta `.planning/` y los tres docume
|
|
|
176
176
|
|
|
177
177
|
---
|
|
178
178
|
|
|
179
|
-
## Fase 3 —
|
|
179
|
+
## Fase 3 — Generar CLAUDE.md raíz del proyecto
|
|
180
|
+
|
|
181
|
+
Antes de cerrar la sesión de inicialización, **genera un `CLAUDE.md` mínimo en
|
|
182
|
+
la raíz del proyecto recién creado**. Es el onboarding script que Claude leerá
|
|
183
|
+
en cada sesión futura sobre este proyecto.
|
|
184
|
+
|
|
185
|
+
> Sigue las best practices del video oficial Anthropic
|
|
186
|
+
> ("The CLAUDE.md file"): empieza compacto, deja que el archivo crezca con
|
|
187
|
+
> correcciones explícitas. Las cinco secciones canónicas son:
|
|
188
|
+
> Stack / Comandos / Code style / Conventions / @references.
|
|
189
|
+
|
|
190
|
+
### Plantilla mínima: `./CLAUDE.md` del proyecto
|
|
191
|
+
|
|
192
|
+
Usa los datos del Bloque B (stack) y del Bloque C (equipo, repo) del cuestionario.
|
|
193
|
+
|
|
194
|
+
```markdown
|
|
195
|
+
# CLAUDE.md — [Nombre del Proyecto]
|
|
196
|
+
|
|
197
|
+
## Stack
|
|
198
|
+
|
|
199
|
+
- **Lenguaje**: [del Bloque B5 / B6]
|
|
200
|
+
- **Framework principal**: [si aplica]
|
|
201
|
+
- **Base de datos**: [del Bloque B7]
|
|
202
|
+
- **Infraestructura**: [del Bloque B6]
|
|
203
|
+
|
|
204
|
+
## Comandos del proyecto
|
|
205
|
+
|
|
206
|
+
| Comando | Propósito |
|
|
207
|
+
|---------|-----------|
|
|
208
|
+
| `[npm run dev / poetry run / etc.]` | Servidor de desarrollo |
|
|
209
|
+
| `[npm test / pytest / cargo test]` | Tests |
|
|
210
|
+
| `[npm run build / ...]` | Build |
|
|
211
|
+
| `[npm run lint / ruff / clippy]` | Lint |
|
|
212
|
+
|
|
213
|
+
## Code style
|
|
214
|
+
|
|
215
|
+
- [Convención de indentación si difiere del default del lenguaje]
|
|
216
|
+
- [Preferencia de exports / módulos si aplica]
|
|
217
|
+
- [Naming si difiere del idiomático del lenguaje]
|
|
218
|
+
|
|
219
|
+
## Conventions
|
|
220
|
+
|
|
221
|
+
- [Convención de organización: dónde van los endpoints / componentes / utils]
|
|
222
|
+
- [Patrones a preferir: ej. "preferir async sobre callbacks"]
|
|
223
|
+
- [Restricciones del Bloque B8 si son operativas]
|
|
224
|
+
|
|
225
|
+
## @references
|
|
226
|
+
|
|
227
|
+
- `@.planning/PROYECTO.md` — visión, objetivos del MVP, criterios de éxito
|
|
228
|
+
- `@.planning/REQUISITOS.md` — requerimientos funcionales y no funcionales
|
|
229
|
+
- `@.planning/HOJA-RUTA.md` — fases planeadas
|
|
230
|
+
|
|
231
|
+
## Cómo evolucionar este archivo
|
|
232
|
+
|
|
233
|
+
1. Empieza mínimo. No adelantes reglas.
|
|
234
|
+
2. Cuando corrijas a Claude, pídele explícitamente: *"guarda esto en CLAUDE.md"*.
|
|
235
|
+
3. Para preferencias personales (no del proyecto), usa `~/.claude/CLAUDE.md`.
|
|
236
|
+
4. Si crece demasiado, ejecuta `/swl:claudemd refactor` para extraer secciones.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Reglas de generación
|
|
240
|
+
|
|
241
|
+
- **Llenar TODOS los placeholders `[...]` con los datos reales del cuestionario**.
|
|
242
|
+
Si falta un dato (ej. el usuario no especificó comandos), dejar el bullet con
|
|
243
|
+
un comentario `<!-- pendiente: confirmar con el equipo -->` en lugar de
|
|
244
|
+
eliminar el bullet o dejarlo vacío.
|
|
245
|
+
- **Mantener el archivo bajo 80 líneas inicialmente**. El video oficial
|
|
246
|
+
recomienda explícitamente "empezar sin uno y construir desde ahí" — la
|
|
247
|
+
primera versión debe ser un esqueleto, no una enciclopedia.
|
|
248
|
+
- **NO incluir reglas que aún no han sido violadas**. Por ejemplo, no
|
|
249
|
+
agregar "no usar `eval()`" si Claude nunca lo usó en este proyecto. Esa
|
|
250
|
+
regla puede vivir como global del usuario o agregarse cuando aparezca el
|
|
251
|
+
primer caso.
|
|
252
|
+
- **NO duplicar información que ya está en `.planning/PROYECTO.md`**. Usar
|
|
253
|
+
`@.planning/PROYECTO.md` como referencia.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Fase 4 — Checklist de arranque
|
|
180
258
|
|
|
181
259
|
Antes de cerrar la sesión de inicialización, verifica:
|
|
182
260
|
|
|
@@ -185,10 +263,12 @@ Antes de cerrar la sesión de inicialización, verifica:
|
|
|
185
263
|
- [ ] El HOJA-RUTA.md tiene fases con duración estimada
|
|
186
264
|
- [ ] Las restricciones "no negociables" están identificadas y documentadas
|
|
187
265
|
- [ ] Se registró quién tomó cada decisión de stack (para futura referencia)
|
|
266
|
+
- [ ] CLAUDE.md raíz generado con secciones canónicas pobladas (Stack, Comandos, @references)
|
|
267
|
+
- [ ] CLAUDE.md raíz validado con `/swl:claudemd audit` (sin warnings)
|
|
188
268
|
|
|
189
269
|
## Gotchas / Errores comunes no obvios
|
|
190
270
|
|
|
191
|
-
- **PROYECTO.md generado con `[TBD]` en restricciones no negociables**: el agente deja campos sin resolver para no bloquear al usuario, pero las restricciones vacías generan retrabajos costosos cuando se descubren tardíamente. Causa: el checklist de cierre de la Fase
|
|
271
|
+
- **PROYECTO.md generado con `[TBD]` en restricciones no negociables**: el agente deja campos sin resolver para no bloquear al usuario, pero las restricciones vacías generan retrabajos costosos cuando se descubren tardíamente. Causa: el checklist de cierre de la Fase 4 no se aplicó rigurosamente. Solución: no cerrar la sesión de inicialización hasta que no quede ningún `[TBD]` en el bloque de restricciones — si el usuario no puede responder, registrar la restricción como "pendiente" en la sección `## Decisiones pendientes` con ticket asignado.
|
|
192
272
|
- **Fase 1 de HOJA-RUTA.md sin duración estimada**: el usuario acepta el documento sin notar que las fases no tienen estimaciones. Causa: el agente genera el template sin poblar las duraciones. Solución: antes de entregar HOJA-RUTA.md, pedir al usuario una estimación rough (días, semanas) para cada fase — sin eso el roadmap es decorativo.
|
|
193
273
|
- **Stack seleccionado sin verificar restricciones del Bloque B**: el agente sugiere un stack "moderno" que viola una restricción de licencia OSS o de plataforma mandatoria del equipo. Causa: el Bloque B se procesó en orden pero las respuestas no se cruzaron con las sugerencias del Bloque A. Solución: al proponer stack, citar explícitamente cada restricción del Bloque B y confirmar que ninguna es violada.
|
|
194
274
|
- **No preguntar por sistemas legados cuando el usuario menciona "reemplazar"**: el agente omite la pregunta 4 del Bloque A asumiendo que el proyecto es greenfield. Causa: mala clasificación del proyecto como nuevo cuando el usuario usó la palabra "reemplazar". Solución: si el usuario menciona "reemplazar", "migrar" o "integrar con" en la descripción, la pregunta 4 es obligatoria, no opcional.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swl-claudemd
|
|
3
|
+
description: Tratamiento profesional de CLAUDE.md según best practices Anthropic (ADR-0016). Cubre auditoría (líneas totales, bullets gigantes, secciones canónicas, @references, placeholders), refactor (extracción a archivos referenciados con @), generación de templates (init-user para preferencias personales transversales en ~/.claude/CLAUDE.md, init-project para CLAUDE.md raíz del proyecto detectando stack). Cargar cuando se invoque /swl:claudemd o cuando el hook claudemd-bloat-detector sugiera intervención.
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
herramientasPermitidas: [Read, Write, Edit, Bash, Glob, Grep]
|
|
6
|
+
exclusiones:
|
|
7
|
+
- "No cargar para editar reglas globales en ~/.claude/rules/ — usar Edit directo."
|
|
8
|
+
- "No cargar para crear ADRs — usar habilidades/doc-coauthoring o Write directo."
|
|
9
|
+
- "No cargar para validar otros archivos (.md de docs, READMEs) — solo CLAUDE.md tiene contrato canónico."
|
|
10
|
+
- "No cargar para generar el bloque del installer en CLAUDE.md de proyectos destino — eso lo hace scripts/lib/transformadores/claude.js."
|
|
11
|
+
evolvable: true
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Habilidad: Tratamiento profesional de CLAUDE.md
|
|
15
|
+
|
|
16
|
+
## Propósito
|
|
17
|
+
|
|
18
|
+
Aplicar las cinco recomendaciones del video oficial Anthropic
|
|
19
|
+
*"The CLAUDE.md file"* (`temp/YouTube · O0FGCxkHM-U.md`) como mecanismo
|
|
20
|
+
verificable y mantenible:
|
|
21
|
+
|
|
22
|
+
1. **Compacto** — empieza sin uno, agrega solo lo que tengas que corregir
|
|
23
|
+
2. **Stack arriba** — lenguaje, framework, ORM, BD
|
|
24
|
+
3. **Commands** — cómo correr dev, tests, lint, build
|
|
25
|
+
4. **Code style** — convenciones de indentación, exports, nombrado
|
|
26
|
+
5. **Conventions** — dónde van las cosas, qué patrones preferir
|
|
27
|
+
|
|
28
|
+
Más dos prácticas auxiliares del video:
|
|
29
|
+
|
|
30
|
+
- **`@filepath`** para referenciar docs en lugar de duplicar contenido
|
|
31
|
+
- **"Ask Claude to save to memory"** — el archivo crece con correcciones
|
|
32
|
+
explícitas, no por adelantar reglas hipotéticas
|
|
33
|
+
|
|
34
|
+
## Cuándo cargar
|
|
35
|
+
|
|
36
|
+
- El usuario invoca `/swl:claudemd [audit|check|refactor|init-user|init-project]`
|
|
37
|
+
- El hook `claudemd-bloat-detector` emite nudge sugiriendo `/swl:claudemd refactor`
|
|
38
|
+
- El usuario pregunta "¿está bien mi CLAUDE.md?" o "¿cómo mejoro mi CLAUDE.md?"
|
|
39
|
+
- Se está generando un proyecto nuevo y se necesita CLAUDE.md raíz
|
|
40
|
+
- Se está cambiando de máquina y se necesita transportar `~/.claude/CLAUDE.md`
|
|
41
|
+
|
|
42
|
+
## Cuándo NO cargar
|
|
43
|
+
|
|
44
|
+
- El usuario quiere editar `~/.claude/rules/*.md` (reglas globales) — usar Edit directo
|
|
45
|
+
- El usuario quiere validar otros `.md` (READMEs, docs/) — no aplica el contrato canónico de CLAUDE.md
|
|
46
|
+
- El usuario quiere generar el bloque del installer — eso lo hace `scripts/lib/transformadores/claude.js`
|
|
47
|
+
- El usuario quiere crear un ADR — usar `Skill("doc-coauthoring")` o Write directo
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Subcomando: audit
|
|
52
|
+
|
|
53
|
+
Ejecuta el auditor determinista:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node scripts/auditar-claudemd.js
|
|
57
|
+
node scripts/auditar-claudemd.js --json # para parsing
|
|
58
|
+
node scripts/auditar-claudemd.js --strict # exit 1 si WARN
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
El auditor verifica seis dimensiones:
|
|
62
|
+
|
|
63
|
+
| Dimensión | Regla | Severidad |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Existencia | Archivo presente en `./CLAUDE.md` o `./.claude/CLAUDE.md` | ERROR si ausente |
|
|
66
|
+
| Tamaño total | Líneas ≤ `SWL_CLAUDEMD_MAX_LINES` (default 200) | WARN |
|
|
67
|
+
| Bullets monolíticos | Cada bullet/párrafo ≤ `SWL_CLAUDEMD_MAX_BULLET_CHARS` (default 1000). Tablas y bloques de código se ignoran | WARN |
|
|
68
|
+
| Secciones canónicas | Stack, Comandos, Code style, Conventions presentes | WARN |
|
|
69
|
+
| @references | Archivos >80 líneas usan al menos un `@docs/...md` | WARN |
|
|
70
|
+
| Placeholders | `[TBD]`, `[TODO]`, `[COMPLETAR]` | ERROR |
|
|
71
|
+
|
|
72
|
+
Veredicto final: ERROR → WARN → OK (el más severo gana).
|
|
73
|
+
|
|
74
|
+
### Cómo interpretar los resultados
|
|
75
|
+
|
|
76
|
+
- **OK**: el archivo cumple. No hay acción requerida.
|
|
77
|
+
- **WARN líneas**: el archivo creció demasiado. Ejecuta `refactor` para
|
|
78
|
+
identificar candidatos a extracción.
|
|
79
|
+
- **WARN bullet gigante**: un bullet/párrafo es ilegible. Convertirlo a
|
|
80
|
+
tabla, lista jerárquica, o extraer su contenido a archivo separado.
|
|
81
|
+
- **WARN secciones ausentes**: las secciones canónicas Anthropic no
|
|
82
|
+
están. Si el archivo es proyecto greenfield, agregarlas. Si es CLAUDE.md
|
|
83
|
+
de overview/meta-sistema, considerar si aplica el contrato.
|
|
84
|
+
- **WARN sin @references**: el archivo es grande pero no enlaza nada
|
|
85
|
+
externo. Identificar contenido duplicable a `@docs/`, `@.planning/`, etc.
|
|
86
|
+
- **ERROR placeholders**: bloqueador. Resolver antes de commitear.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Subcomando: refactor
|
|
91
|
+
|
|
92
|
+
**No modifica archivos** — propone diff. El usuario decide aplicar.
|
|
93
|
+
|
|
94
|
+
### Algoritmo
|
|
95
|
+
|
|
96
|
+
1. Lee `CLAUDE.md` actual.
|
|
97
|
+
2. Para cada bullet/párrafo > `MAX_BULLET_CHARS`:
|
|
98
|
+
- Si contiene **una sola lista de items homogéneos** → propone tabla
|
|
99
|
+
- Si contiene **definiciones técnicas extensas** → propone extracción a `docs/[tema].md`
|
|
100
|
+
- Si contiene **enumeración de variables/configuración** → propone extracción a `docs/variables-[scope].md`
|
|
101
|
+
3. Para cada sección > 50 líneas:
|
|
102
|
+
- Identifica el "tema" del header
|
|
103
|
+
- Propone `docs/[tema-kebab].md` y reemplazo en CLAUDE.md por:
|
|
104
|
+
`Para detalles ver @docs/[tema].md`
|
|
105
|
+
4. Imprime diff propuesto en formato unified.
|
|
106
|
+
|
|
107
|
+
### Patrones de extracción típicos
|
|
108
|
+
|
|
109
|
+
| Si la sección/bullet contiene… | Mover a… |
|
|
110
|
+
|---|---|
|
|
111
|
+
| Variables de entorno opt-in | `docs/variables-entorno.md` |
|
|
112
|
+
| Reglas de gobernanza extensas | `docs/gobernanza.md` |
|
|
113
|
+
| Catálogo completo de comandos | `COMANDOS.md` (referenciar) |
|
|
114
|
+
| Mapa de propagación detallado | `docs/mapa-propagacion.md` |
|
|
115
|
+
| Convenciones por capa | `docs/convenciones-{capa}.md` |
|
|
116
|
+
| Lista de dependencias / stack histórico | `docs/stack-historico.md` |
|
|
117
|
+
| Decisiones puntuales antiguas | ADR en `.planning/adrs/` |
|
|
118
|
+
|
|
119
|
+
### Anti-patrones de refactor
|
|
120
|
+
|
|
121
|
+
- **NO extraer reglas de máxima prioridad** — esas DEBEN estar en CLAUDE.md raíz
|
|
122
|
+
- **NO extraer la sección Stack** — es la primera info que Claude necesita
|
|
123
|
+
- **NO extraer la sección Commands** — son acción inmediata, deben estar visibles
|
|
124
|
+
- **NO crear más de 3 archivos `@`-referenciados nuevos en un solo refactor** — fragmentar demasiado dispersa el contexto
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Subcomando: init-user
|
|
129
|
+
|
|
130
|
+
Genera `~/.claude/CLAUDE.md` (en Windows: `%USERPROFILE%\.claude\CLAUDE.md`)
|
|
131
|
+
con template de preferencias personales si NO existe. Si existe, sugiere
|
|
132
|
+
secciones faltantes pero NO sobreescribe.
|
|
133
|
+
|
|
134
|
+
### Pasos
|
|
135
|
+
|
|
136
|
+
1. Detectar la ruta:
|
|
137
|
+
- Linux/macOS: `$HOME/.claude/CLAUDE.md`
|
|
138
|
+
- Windows: `$env:USERPROFILE/.claude/CLAUDE.md` (en PowerShell)
|
|
139
|
+
2. Si existe → leer, identificar secciones faltantes, sugerir patches
|
|
140
|
+
3. Si no existe → crear directorio `~/.claude/` si falta, escribir template
|
|
141
|
+
|
|
142
|
+
### Template
|
|
143
|
+
|
|
144
|
+
Ver template completo en el comando `/swl:claudemd` sección `init-user`.
|
|
145
|
+
|
|
146
|
+
Las secciones canónicas para user-level son DISTINTAS de project-level:
|
|
147
|
+
|
|
148
|
+
| Sección | Project-level | User-level |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| Stack | Sí — del proyecto | No (varía por proyecto) |
|
|
151
|
+
| Comandos | Sí — del proyecto | No |
|
|
152
|
+
| Code style | Sí — convenciones del equipo | Sí — preferencias personales (indent, naming favorito) |
|
|
153
|
+
| Conventions | Sí — del proyecto | No |
|
|
154
|
+
| Mi rol y stack preferido | No | Sí |
|
|
155
|
+
| Estilo de comunicación | No | Sí |
|
|
156
|
+
| Patrones que aplico siempre | No | Sí — meta-preferencias cross-project |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Subcomando: init-project
|
|
161
|
+
|
|
162
|
+
Genera `./CLAUDE.md` raíz del proyecto detectando stack actual.
|
|
163
|
+
|
|
164
|
+
### Pasos
|
|
165
|
+
|
|
166
|
+
1. Verificar que `./CLAUDE.md` NO exista. Si existe → mensaje "ya existe,
|
|
167
|
+
considera `/swl:claudemd refactor`" y salir sin tocar.
|
|
168
|
+
2. Ejecutar `detectarStackDetallado(process.cwd())` (de
|
|
169
|
+
`scripts/lib/detectar-stack-detallado.js`).
|
|
170
|
+
3. Generar archivo con secciones pobladas:
|
|
171
|
+
- **Stack**: lenguaje + framework + ORM + package manager detectados
|
|
172
|
+
- **Comandos**: npm scripts detectados o comandos típicos por lenguaje
|
|
173
|
+
- **Code style**: placeholders explícitos (`<!-- pendiente: definir convención de X -->`)
|
|
174
|
+
- **Conventions**: placeholders explícitos
|
|
175
|
+
- **@references**: enlazar a `.planning/PROYECTO.md`, `README.md`,
|
|
176
|
+
`CONTRIBUTING.md` solo si existen
|
|
177
|
+
4. Imprimir mensaje con próximo paso: "ejecuta `/swl:claudemd audit`
|
|
178
|
+
para verificar".
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Gotchas / Errores comunes no obvios
|
|
183
|
+
|
|
184
|
+
- **Marcar tablas como bullets gigantes**: el detector debe excluir
|
|
185
|
+
líneas que empiezan con `|` (tablas Markdown). Sin ese filtro genera
|
|
186
|
+
falsos positivos en cualquier CLAUDE.md con tablas. Implementado en
|
|
187
|
+
`scripts/auditar-claudemd.js` función `detectarBulletsGigantes`.
|
|
188
|
+
- **Marcar bloques de código como bullets gigantes**: igual que tablas
|
|
189
|
+
— el detector entra en modo "code fence" al ver ` ``` ` y no cuenta
|
|
190
|
+
esas líneas. Sin ese filtro un script Bash de 50 líneas en CLAUDE.md
|
|
191
|
+
rompe la auditoría.
|
|
192
|
+
- **`refactor` que termina escribiendo el archivo**: el subcomando
|
|
193
|
+
refactor SOLO debe imprimir diff. Si modifica el archivo viola el
|
|
194
|
+
principio "el usuario decide". Cualquier modificación destructiva debe
|
|
195
|
+
ser explícita y confirmada por el usuario.
|
|
196
|
+
- **`init-project` sobreescribiendo CLAUDE.md existente**: el usuario
|
|
197
|
+
puede tener un CLAUDE.md curado con valor irrecuperable. NUNCA
|
|
198
|
+
sobreescribir — sugerir refactor.
|
|
199
|
+
- **Templates con `[TBD]` que después fallan auditoría**: los templates
|
|
200
|
+
generados por `init-user` y `init-project` usan `<!-- pendiente: ... -->`
|
|
201
|
+
HTML comments en lugar de `[TBD]` para que el auditor no los marque
|
|
202
|
+
como ERROR placeholders. Comments HTML son ignorados por el regex.
|
|
203
|
+
- **Aplicar el contrato canónico a CLAUDE.md de subdirectorios**: si el
|
|
204
|
+
proyecto adopta jerarquía (ADR-0007), los CLAUDE.md de subdirectorios
|
|
205
|
+
pueden NO tener todas las secciones canónicas (porque heredan del root).
|
|
206
|
+
Por ahora el auditor aplica el contrato uniforme; si el ADR-0007 se
|
|
207
|
+
acepta, el auditor debe distinguir root vs subdirectorio.
|
|
208
|
+
|
|
209
|
+
## Señales de alerta
|
|
210
|
+
|
|
211
|
+
Detente y escala si:
|
|
212
|
+
|
|
213
|
+
- El usuario pide `init-project` en un directorio que ya tiene CLAUDE.md
|
|
214
|
+
con >100 líneas de contenido custom (riesgo: pérdida de información)
|
|
215
|
+
- `audit` reporta WARN líneas pero el contenido es legítimamente
|
|
216
|
+
necesario (ej. listas grandes de comandos sin posibilidad de extracción
|
|
217
|
+
útil) — sugerir ajustar `SWL_CLAUDEMD_MAX_LINES`, no extraer por extraer
|
|
218
|
+
- El usuario pide `refactor` y propone extracciones que dispersarían
|
|
219
|
+
contexto crítico (ej. mover "Reglas de máxima prioridad") — rechazar
|
|
220
|
+
con explicación del anti-patrón
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook: claudemd-bloat-detector.js
|
|
6
|
+
* Tipo: PostToolUse (aplica a: Write, Edit, MultiEdit)
|
|
7
|
+
*
|
|
8
|
+
* Ejecuta `scripts/auditar-claudemd.js` contra archivos `CLAUDE.md`
|
|
9
|
+
* recién modificados y emite un nudge a `.planning/evolucion/nudges.jsonl`
|
|
10
|
+
* si el veredicto es WARN o ERROR.
|
|
11
|
+
*
|
|
12
|
+
* Aplica ADR-0016 (best practices Anthropic "The CLAUDE.md file"):
|
|
13
|
+
* detecta inflación (líneas excesivas, bullets monolíticos, secciones
|
|
14
|
+
* canónicas ausentes, ausencia de @references) y sugiere intervención
|
|
15
|
+
* con `/swl:claudemd refactor`.
|
|
16
|
+
*
|
|
17
|
+
* Opt-out: SWL_CLAUDEMD_BLOAT=0 desactiva completamente el hook.
|
|
18
|
+
*
|
|
19
|
+
* Comportamiento:
|
|
20
|
+
* - Nunca bloquea operaciones (exit code 0 siempre)
|
|
21
|
+
* - Solo emite nudge cuando veredicto != OK — ruido mínimo
|
|
22
|
+
* - Solo se dispara con archivos cuyo basename sea exactamente CLAUDE.md
|
|
23
|
+
* - Respeta exclusiones: temp/, node_modules/, respositorios-git/
|
|
24
|
+
*
|
|
25
|
+
* Formato del nudge:
|
|
26
|
+
* {
|
|
27
|
+
* id: string,
|
|
28
|
+
* kind: "claudemd-bloat",
|
|
29
|
+
* target: "documentador-swl",
|
|
30
|
+
* source: "hooks/claudemd-bloat-detector.js",
|
|
31
|
+
* message: "...",
|
|
32
|
+
* data: { archivo, veredicto, lineas, hallazgos_count },
|
|
33
|
+
* ts: ISO,
|
|
34
|
+
* accionado: false
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
const fs = require('fs');
|
|
39
|
+
const path = require('path');
|
|
40
|
+
const crypto = require('crypto');
|
|
41
|
+
|
|
42
|
+
// ─── Opt-out global ───────────────────────────────────────────────────────
|
|
43
|
+
if (process.env.SWL_CLAUDEMD_BLOAT === '0') {
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let hookInput = '';
|
|
48
|
+
try {
|
|
49
|
+
hookInput = fs.readFileSync(0, 'utf-8');
|
|
50
|
+
} catch (_) {
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let evento;
|
|
55
|
+
try {
|
|
56
|
+
evento = JSON.parse(hookInput);
|
|
57
|
+
} catch (_) {
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const toolName = evento?.tool_name;
|
|
62
|
+
const toolInput = evento?.tool_input;
|
|
63
|
+
|
|
64
|
+
if (!toolName || !['Write', 'Edit', 'MultiEdit'].includes(toolName)) {
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const filePath = toolInput?.file_path;
|
|
69
|
+
if (!filePath) {
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Solo CLAUDE.md (basename exacto, case-sensitive)
|
|
74
|
+
const basename = path.basename(filePath);
|
|
75
|
+
if (basename !== 'CLAUDE.md') {
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const pathNormalized = filePath.replace(/\\/g, '/');
|
|
80
|
+
const RUTAS_EXCLUIDAS = [
|
|
81
|
+
'/temp/',
|
|
82
|
+
'/node_modules/',
|
|
83
|
+
'/respositorios-git/',
|
|
84
|
+
'/.planning/',
|
|
85
|
+
];
|
|
86
|
+
if (RUTAS_EXCLUIDAS.some((excluida) => pathNormalized.includes(excluida))) {
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// El archivo debe existir
|
|
91
|
+
if (!fs.existsSync(filePath)) {
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ─── Ejecutar auditor (módulo, no subproceso) ─────────────────────────────
|
|
96
|
+
const CWD = process.cwd();
|
|
97
|
+
const auditorPath = path.join(CWD, 'scripts', 'auditar-claudemd.js');
|
|
98
|
+
if (!fs.existsSync(auditorPath)) {
|
|
99
|
+
// No hay auditor instalado en este destino; salir silenciosamente
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let resultado;
|
|
104
|
+
try {
|
|
105
|
+
const { auditar } = require(auditorPath);
|
|
106
|
+
resultado = auditar(filePath);
|
|
107
|
+
} catch (_) {
|
|
108
|
+
// Cualquier error del auditor: salir silenciosamente, no romper el hook
|
|
109
|
+
process.exit(0);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Solo emitir nudge si veredicto != OK
|
|
113
|
+
if (!resultado || resultado.veredicto === 'OK') {
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ─── Construir nudge ──────────────────────────────────────────────────────
|
|
118
|
+
const rutaRelativa = path.relative(CWD, filePath).replace(/\\/g, '/');
|
|
119
|
+
const topHallazgos = (resultado.hallazgos || [])
|
|
120
|
+
.slice(0, 3)
|
|
121
|
+
.map((h) => ` - [${h.severidad}] ${h.mensaje}`)
|
|
122
|
+
.join('\n');
|
|
123
|
+
|
|
124
|
+
const nudge = {
|
|
125
|
+
id: crypto.randomBytes(8).toString('hex'),
|
|
126
|
+
kind: 'claudemd-bloat',
|
|
127
|
+
target: 'documentador-swl',
|
|
128
|
+
source: 'hooks/claudemd-bloat-detector.js',
|
|
129
|
+
message:
|
|
130
|
+
`[claudemd] ${rutaRelativa} veredicto: ${resultado.veredicto} ` +
|
|
131
|
+
`(${resultado.hallazgos.length} hallazgos)\n` +
|
|
132
|
+
topHallazgos + '\n' +
|
|
133
|
+
` Ejecutar \`/swl:claudemd audit\` para detalle, ` +
|
|
134
|
+
`\`/swl:claudemd refactor\` para sugerencias de extracción.`,
|
|
135
|
+
data: {
|
|
136
|
+
archivo: rutaRelativa,
|
|
137
|
+
veredicto: resultado.veredicto,
|
|
138
|
+
lineas: resultado.metricas?.lineas,
|
|
139
|
+
secciones_ausentes: resultado.metricas?.secciones_ausentes || [],
|
|
140
|
+
tiene_at_references: resultado.metricas?.tiene_at_references,
|
|
141
|
+
hallazgos_count: resultado.hallazgos.length,
|
|
142
|
+
},
|
|
143
|
+
ts: new Date().toISOString(),
|
|
144
|
+
accionado: false,
|
|
145
|
+
accionado_ts: null,
|
|
146
|
+
accionado_por: null,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// ─── Persistir a nudges.jsonl ─────────────────────────────────────────────
|
|
150
|
+
try {
|
|
151
|
+
const nudgesPath = path.join(CWD, '.planning', 'evolucion', 'nudges.jsonl');
|
|
152
|
+
const nudgesDir = path.dirname(nudgesPath);
|
|
153
|
+
if (!fs.existsSync(nudgesDir)) {
|
|
154
|
+
fs.mkdirSync(nudgesDir, { recursive: true });
|
|
155
|
+
}
|
|
156
|
+
fs.appendFileSync(nudgesPath, JSON.stringify(nudge) + '\n', 'utf-8');
|
|
157
|
+
} catch (_) {
|
|
158
|
+
// No fallar el hook por error de escritura
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
process.exit(0);
|
|
@@ -347,6 +347,15 @@
|
|
|
347
347
|
"maxConsecutiveFailures": 5,
|
|
348
348
|
"degradeOnFailure": "skip"
|
|
349
349
|
},
|
|
350
|
+
"claudemd-bloat-detector.js": {
|
|
351
|
+
"event": "PostToolUse",
|
|
352
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
353
|
+
"description": "Ejecuta scripts/auditar-claudemd.js contra archivos CLAUDE.md recién modificados (basename exacto, no cualquier .md). Emite nudge a .planning/evolucion/nudges.jsonl si veredicto != OK (líneas excesivas, bullets gigantes, secciones canónicas ausentes, sin @references, placeholders). Aplica ADR-0016 (best practices Anthropic 'The CLAUDE.md file'). No bloquea. Excluye temp/, node_modules/, respositorios-git/, .planning/. Opt-out: SWL_CLAUDEMD_BLOAT=0.",
|
|
354
|
+
"blocking": false,
|
|
355
|
+
"async": true,
|
|
356
|
+
"maxConsecutiveFailures": 5,
|
|
357
|
+
"degradeOnFailure": "skip"
|
|
358
|
+
},
|
|
350
359
|
"notificacion-telegram.js": {
|
|
351
360
|
"event": "Stop",
|
|
352
361
|
"matcher": "",
|