@saulwade/swl-ses 1.2.1 → 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/fastapi-experto/SKILL.md +6 -4
- package/habilidades/nextjs-experto/SKILL.md +12 -1
- package/habilidades/nuevo-proyecto/SKILL.md +82 -2
- package/habilidades/react-experto/SKILL.md +16 -1
- 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
|
|
@@ -5,12 +5,12 @@ description: >
|
|
|
5
5
|
testing con httpx. Incluye el anti-patrón crítico MissingGreenlet (lazy loading
|
|
6
6
|
en async). Cargar cuando se implementen endpoints FastAPI, schemas Pydantic v2,
|
|
7
7
|
queries SQLAlchemy async, WebSockets, SSE o tests de integración con httpx.
|
|
8
|
-
version: "1.
|
|
8
|
+
version: "1.2.0"
|
|
9
9
|
evolved: true
|
|
10
|
-
evolved-from: "1.1.
|
|
11
|
-
evolved-at: "2026-05-
|
|
10
|
+
evolved-from: "1.1.2"
|
|
11
|
+
evolved-at: "2026-05-10"
|
|
12
12
|
evolved-by: "aprender"
|
|
13
|
-
evolved-note: "
|
|
13
|
+
evolved-note: "2 reglas nuevas en sesión SIGM Opción B: response_model=dict obsoleto vs Envelope[T] tipado, RETURNING * sin soporte de JOINs (refactor a 2 queries con _SQL_X_ENRIQUECIDA)"
|
|
14
14
|
herramientasPermitidas: [Read]
|
|
15
15
|
exclusiones:
|
|
16
16
|
- "No cargar para proyectos Django o Flask — los patrones de ORM sync, Class-Based Views y middleware difieren fundamentalmente; cargar `django-experto` o el skill del framework correspondiente."
|
|
@@ -219,6 +219,8 @@ class Factura(Base):
|
|
|
219
219
|
- **`return result or {}` después de UPDATE/INSERT enmascara errores de BD silenciosamente**: patrón típico `result = await repo.actualizar_estatus(...); return result or {}` devuelve `{}` al cliente cuando el UPDATE no encontró la fila (race condition, RLS, FK violado). El cliente recibe HTTP 200 con body vacío en lugar del 404/500 esperado, los bugs quedan invisibles en monitoring. Causa: `or {}` trata `None` como "datos no disponibles" cuando en realidad significa "el UPDATE falló post-INSERT". Solución: explicit None check con raise — usar `if result is None: raise HTTPException(404, "Recurso no encontrado")` cuando el ID viene del cliente, o `raise HTTPException(500, "Error interno...")` cuando es un invariante post-INSERT (la fila acaba de crearse, debe existir).
|
|
220
220
|
- **`detail=str(exc)` en HTTPException — solo aceptable cuando la excepción es de DOMINIO con mensaje diseñado para usuario**: las excepciones de capa externa (MinIO/S3, BD driver, HTTP client de un PSP, parser PDF) tienen mensajes que pueden contener bucket/host/paths/credenciales parciales/stack traces. Pasar `str(exc)` directo al `detail` los expone al cliente. Causa: tratar todas las excepciones igual sin distinguir dominio (controlado) de capa externa (no controlado). Solución: dos patrones distintos. Para excepciones de dominio (`MIMENoPermitidoError("MIME 'X' no permitido")`, `EmailDuplicadoError`): `except DominioError as exc: raise HTTPException(422, detail=str(exc))` OK. Para capa externa (`ErrorEvidencia`, `boto3.ClientError`, `httpx.RequestError`): `except CapaExternaError as exc: logger.exception("contexto"); raise HTTPException(502, detail="Error genérico al cliente")`. La diferencia es que el mensaje de DominioError fue diseñado para el usuario; el de CapaExternaError no.
|
|
221
221
|
- **Vocabulario interno (nombres de funciones PL/pgSQL, schemas, tablas, "RLS", "transaccional") en `detail` al cliente fuga arquitectura**: detail genérico al cliente y detail con detalles de infraestructura para diagnóstico **no son lo mismo**. Patrones de fuga típicos: `detail=f"fn_evaluar_X no retornó resultado"` (revela nombre de función PL/pgSQL), `detail="Posible inconsistencia transaccional o RLS"` (revela motor + capa de seguridad), `detail=f"Recurso {id} no encontrado en activacion tras INSERT"` (revela UUID interno y secuencia de operaciones). Causa: el desarrollador escribe el mensaje pensando en debug, no en exposición. Solución: detail al cliente = mensaje genérico orientado al recurso ("Error interno al activar el recurso. Contacte al administrador."); detalles internos solo en `logger.error("contexto detallado %s %s", uuid, programa_id, ...)` con format strings estructurados (NO concatenación con `+`). Aplica a todos los HTTPException 500/503; el 404/422 puede ser más específico si el mensaje es del dominio.
|
|
222
|
+
- **`response_model=dict` produce `{[key:string]:unknown}` en `openapi-typescript` — tipos inútiles para frontend**: declarar endpoints con `response_model=dict` (placeholder) hace que el codegen `openapi-typescript` genere responses tipados como objeto vacío. El frontend lee campos via `.id`, `.monto` con type assertions implícitas → mismatches silenciosos en runtime cuando los nombres del backend cambian. Causa: FastAPI sin schema concreto no documenta el shape en `/openapi.json`. Fix: SIEMPRE declarar `response_model=EnvelopeResponse[Schema]`, `EnvelopePaginatedResponse[Schema]`, `EnvelopeOffsetResponse[Schema]` o `EnvelopeResponse[MensajeResponse]` con un schema Pydantic concreto. Genéricos `EnvelopeResponse[T] / EnvelopePaginatedResponse[T] / EnvelopeOffsetResponse[T] / MensajeResponse` deben vivir en `app/common/response.py` (Pydantic v2 + Generic[T]). Excepción única documentable: `StreamingResponse` (PDF/CSV) puede usar `response_model=dict` con comentario explicativo. Caso real: 155 endpoints SIGM refactorizados (2026-05-10) tras descubrir que el codegen producía tipos vacíos por `response_model=dict` heredado.
|
|
223
|
+
- **Pydantic + PostgreSQL `RETURNING *` no soporta JOINs en INSERT/UPDATE — refactor a 2 queries**: para mutaciones que devuelven un schema enriquecido con JOINs (ej: `cajero_nombre` desde `usuario.usuario`, `clave_catastral` desde `cuenta_predial`), `INSERT/UPDATE ... RETURNING *` no permite agregar JOINs. Causa: PostgreSQL `RETURNING` solo accede a las columnas de la tabla afectada. Fix: refactorizar a 2 queries: (1) `INSERT/UPDATE ... RETURNING id`; (2) `SELECT ... FROM tabla LEFT JOIN ... WHERE id = $1`. Costo: 1 round-trip extra (sub-1ms en LAN). Beneficio: el método siempre devuelve el shape enriquecido, mappers consistentes entre `crear`, `obtener` y `listar`. Patrón DRY: extraer la query SELECT a constante de clase (`_SQL_X_ENRIQUECIDA`) para reusar entre métodos. Caso: `crear_solicitud_descuento`, `autorizar_descuento`, `obtener_solicitud_descuento` y `listar_solicitudes_pendientes` comparten `_SQL_SOLICITUD_ENRIQUECIDA` con LEFT JOIN a `cuenta_predial` + `usuario` (cajero/supervisor).
|
|
222
224
|
|
|
223
225
|
## Referencias especializadas
|
|
224
226
|
|
|
@@ -4,7 +4,12 @@ description: >
|
|
|
4
4
|
Next.js App Router: Server Components, Client Components, Server Actions,
|
|
5
5
|
streaming con Suspense, ISR, route handlers y middleware. Cargar cuando se
|
|
6
6
|
implementen páginas Next.js, data fetching, mutaciones o rutas de API.
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.1.0"
|
|
8
|
+
evolved: true
|
|
9
|
+
evolved-from: "1.0.0"
|
|
10
|
+
evolved-at: "2026-05-10"
|
|
11
|
+
evolved-by: "aprender"
|
|
12
|
+
evolved-note: "3 gotchas operativos confirmados en sesión SIGM Opción B: useSearchParams Suspense bailout, cache .next stale, brace-expansion override CVE-2025-5889"
|
|
8
13
|
herramientasPermitidas: [Read]
|
|
9
14
|
exclusiones:
|
|
10
15
|
- "No cargar para proyectos Next.js con Pages Router (pages/index.tsx) — el modelo de getServerSideProps y getStaticProps es diferente al App Router; este skill solo cubre App Router."
|
|
@@ -316,6 +321,12 @@ export default function Reloj() {
|
|
|
316
321
|
|
|
317
322
|
**Variables de entorno sin `NEXT_PUBLIC_` no disponibles en el cliente en runtime**: `process.env.MI_VAR` en un Client Component retorna `undefined` en el browser aunque esté definida en `.env.local`. Causa: Next.js solo serializa al bundle del cliente las variables con prefijo `NEXT_PUBLIC_`. Fix: renombrar a `NEXT_PUBLIC_MI_VAR` si debe estar en el cliente, o leerla en un Server Component/Action y pasarla como prop.
|
|
318
323
|
|
|
324
|
+
**`useSearchParams()` requiere `<Suspense>` boundary durante prerender estático**: build de producción falla con `⨯ useSearchParams() should be wrapped in a suspense boundary at page "/X". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout`. Causa: el prerender estático no puede ejecutar el hook → CSR bailout → build aborta. Fix: en `page.tsx` envolver el componente que usa `useSearchParams()` en `<Suspense fallback={null}>` (o un esqueleto). El shell se prerenderiza vacío; el componente hidrata en cliente con los search params disponibles. Mismo patrón aplica a `useRouter()` y `usePathname()` cuando se usan en componentes prerenderizados. Caso real: SIGM agregó `useSearchParams()` a `useLoginForm.ts` para honrar `?siguiente=`; tsc + vitest pasaban pero `npm run build` falló hasta envolver `<LoginForm />` en `<Suspense>`.
|
|
325
|
+
|
|
326
|
+
**Cache `.next/` puede ocultar errores TypeScript reales tras refactor de tipos masivo**: `npx tsc --noEmit` local pasa pero CI falla con errores TS2724/TS2305 sobre tipos eliminados. Causa: `.next/types/*.d.ts` y `tsconfig.tsbuildinfo` cachean los types del estado anterior; CI clona limpio y ve los errores reales. Fix: cuando se modifican imports/exports masivos en `lib/*/tipos.ts` (refactor de tipos, eliminación de interfaces, codegen openapi-typescript), borrar cache antes de validar local: `cd frontend && rm -rf .next && npx tsc --noEmit`. Si CI falla con TSC y local pasa: 90% de las veces es cache stale.
|
|
327
|
+
|
|
328
|
+
**Override de `brace-expansion@^5` rompe minimatch (eslint depende)**: `npm install` aplica el override pero `eslint . --ext .ts,.tsx` falla con `TypeError: expand is not a function` en `@eslint/config-array → minimatch → brace-expansion`. Causa: brace-expansion v3+ cambió la API (de export default `expand` function a export con shape distinto); minimatch espera la API v2. Fix: para CVE-2025-5889 (ReDoS), usar `"brace-expansion": "^2.0.2"` (parcheado desde 2.0.2 — NO requiere v5). Validación pre-override: `npm ls brace-expansion` para revisar consumidores conocidos antes de bumpear major. Mismo patrón aplicable a otros overrides de transitives — validar cadena de consumers antes de bumpear major.
|
|
329
|
+
|
|
319
330
|
## Checklist de verificación
|
|
320
331
|
|
|
321
332
|
- [ ] "use client" solo en componentes con hooks, eventos o browser APIs
|
|
@@ -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.
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: react-experto
|
|
3
3
|
description: React + Next.js mejores prácticas modernas. Cubre Server Components vs Client Components, data fetching patterns (RSC, React Query, SWR, Server Actions), state management (useState, Zustand, Jotai), performance (memo, lazy, Suspense, streaming) y Next.js App Router patterns.
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.1.0"
|
|
5
|
+
evolved: true
|
|
6
|
+
evolved-from: "1.0.0"
|
|
7
|
+
evolved-at: "2026-05-10"
|
|
8
|
+
evolved-by: "aprender"
|
|
9
|
+
evolved-note: "Patrón useSyncExternalStore para hidratación cliente-only confirmado en sesión SIGM (evita la regla nueva react-hooks/set-state-in-effect)"
|
|
5
10
|
herramientasPermitidas: [Read]
|
|
6
11
|
exclusiones:
|
|
7
12
|
- "No cargar para optimización de rendimiento React (memo, useMemo, useCallback, virtualización, code splitting) — para rendimiento cargar `react-optimizacion`."
|
|
@@ -207,3 +212,13 @@ Para ejemplos completos de React Query (mutations + invalidacion), Server Action
|
|
|
207
212
|
**Server Action que actualiza datos sin `revalidatePath` o `revalidateTag` muestra datos obsoletos**: después de un Server Action exitoso (crear/actualizar/eliminar), el cliente sigue viendo el caché anterior del RSC. Causa: Next.js cachea agresivamente los datos del servidor; los Server Actions no invalidan el caché automáticamente. Fix: llamar `revalidatePath('/ruta/afectada')` o `revalidateTag('tag-del-dato')` al final del Server Action antes de `redirect()` o `return`.
|
|
208
213
|
|
|
209
214
|
**`useState` con objeto como valor inicial no se actualiza con shallow comparison en re-renders del padre**: `useState({ nombre: '', email: '' })` inicializa el estado una sola vez — si el componente padre pasa nuevos valores como prop para reinicializar el formulario, el estado no se actualiza. Causa: `useState` solo usa el valor inicial en el primer render. Fix: usar `key` en el componente para forzar remonte cuando cambien los datos base, o usar `useEffect` con las props como dependencias para sincronizar explícitamente.
|
|
215
|
+
|
|
216
|
+
**Patrón `useState + useEffect(() => setState(true), [])` para detectar cliente dispara la regla `react-hooks/set-state-in-effect` en eslint-plugin-react-hooks v7+**: build CI falla con `Calling setState synchronously within an effect body causes cascading renders`. Causa: la regla nueva (Next.js 16+) detecta el patrón clásico de "mounted flag" para hidratación segura como anti-patrón de performance. Fix idiomático React 19: usar `useSyncExternalStore`:
|
|
217
|
+
```tsx
|
|
218
|
+
const mounted = useSyncExternalStore(
|
|
219
|
+
() => () => {}, // subscribe — no-op (la 'store' no cambia tras hidratación)
|
|
220
|
+
() => true, // getSnapshot — cliente siempre montado
|
|
221
|
+
() => false, // getServerSnapshot — SSR siempre 'no montado'
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
Equivalente funcional al patrón mounted flag, sin disparar la regla. Type-safe, lint-compliant. Usar en Header/Sidebar/cualquier componente que lea localStorage o `window` y necesite render distinto en SSR vs cliente.
|
|
@@ -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
|