@saulwade/swl-ses 1.3.8 → 1.4.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 +12 -4
- package/README.md +1 -1
- package/bin/swl-mcp-server.js +187 -187
- package/bin/swl-webhook-server.js +198 -0
- package/comandos/swl/.evolved.json +22 -22
- package/comandos/swl/adoptar-proyecto.md +21 -1
- package/comandos/swl/claudemd.md +14 -1
- package/comandos/swl/contribuir.md +233 -233
- package/comandos/swl/exportar-vault.md +108 -0
- package/comandos/swl/nuevo-proyecto.md +24 -2
- package/gateway/adapters/base.js +109 -0
- package/gateway/adapters/discord.js +167 -0
- package/gateway/adapters/email.js +221 -0
- package/gateway/adapters/slack.js +192 -0
- package/gateway/adapters/telegram.js +183 -0
- package/gateway/adapters/webhook.js +113 -0
- package/gateway/adapters/whatsapp.js +214 -0
- package/gateway/agent-executor.js +322 -0
- package/gateway/command-relay.js +271 -0
- package/gateway/cron/jobs.js +263 -0
- package/gateway/cron/scheduler.js +322 -0
- package/gateway/cron/store.js +335 -0
- package/gateway/index.js +320 -0
- package/gateway/lib/event-channel.js +191 -0
- package/gateway/session.js +131 -0
- package/gateway/webhook-server.js +324 -0
- package/habilidades/backend-production-resilience/SKILL.md +288 -288
- package/habilidades/benchmark-memoria/SKILL.md +186 -186
- package/habilidades/build-errors-nextjs/SKILL.md +55 -1
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
- package/habilidades/doubt-driven-review/SKILL.md +171 -171
- package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
- package/habilidades/eval-framework/SKILL.md +212 -212
- package/habilidades/extractor-de-aprendizajes/SKILL.md +20 -10
- package/habilidades/harness-claude-code/SKILL.md +299 -299
- package/habilidades/infra-github-actions/SKILL.md +166 -166
- package/habilidades/legacy-code-rescue/SKILL.md +267 -267
- package/habilidades/manejo-errores/.evolved.json +8 -8
- package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
- package/habilidades/nextjs-testing/SKILL.md +89 -5
- package/habilidades/node-experto/SKILL.md +37 -1
- package/habilidades/patrones-python/SKILL.md +229 -229
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
- package/habilidades/planear-fase/SKILL.md +319 -319
- package/habilidades/react-experto/SKILL.md +45 -4
- package/habilidades/release-semver/.evolved.json +8 -8
- package/habilidades/tdd-workflow/SKILL.md +36 -4
- package/habilidades/testing-python/SKILL.md +340 -340
- package/hooks/claudemd-bloat-detector.js +161 -161
- package/hooks/inyeccion-contexto.js +8 -3
- package/hooks/lib/agent-routing.js +107 -107
- package/hooks/lib/auto-consolidator.js +335 -335
- package/hooks/lib/error-classifier.js +308 -308
- package/hooks/lib/merkle-audit.js +96 -96
- package/hooks/lib/provenance-tracker.js +191 -191
- package/hooks/lib/rate-limit-ip.js +177 -0
- package/hooks/lib/rate-limit-tracker.js +253 -253
- package/hooks/lib/resource-quota.js +122 -122
- package/hooks/lib/retry-jitter.js +165 -165
- package/hooks/lib/skill-auditor.js +588 -588
- package/hooks/lib/sync-status.js +228 -228
- package/hooks/lib/taint-tracker.js +107 -107
- package/hooks/lib/text-similarity.js +241 -241
- package/hooks/lib/toon-compressor.js +245 -245
- package/hooks/lib/webhook-dedup.js +184 -0
- package/hooks/lib/webhook-verify.js +123 -0
- package/hooks/proteccion-rutas.js +120 -15
- package/hooks/registro-turnos.js +209 -209
- package/hooks/sugerir-regenerar-inventario.js +170 -170
- package/hooks/validar-formato-post-subagente.js +140 -140
- package/hooks/validar-memoria-hook.js +218 -218
- package/instintos/prompt-appendices.yaml +57 -57
- package/manifiestos/agent-output-schemas.json +57 -57
- package/manifiestos/modulos.json +1 -0
- package/manifiestos/skills-lock.json +34 -34
- package/package.json +5 -3
- package/plantillas/auditor-veto-template.md +105 -105
- package/plantillas/github-workflows/README.md +47 -47
- package/plantillas/github-workflows/release-please.yml +44 -44
- package/plantillas/github-workflows/swl-ci.yml +107 -107
- package/plantillas/github-workflows/swl-security.yml +51 -51
- package/plugin.json +1 -1
- package/reglas/analisis-previo-tareas-grandes.md +172 -172
- package/reglas/arreglar-al-detectar.md +147 -147
- package/reglas/fragmentos-compartidos.md +152 -152
- package/reglas/harness-claude-code.md +213 -213
- package/reglas/usar-context7.md +226 -226
- package/reglas/usar-sistema-swl.md +251 -0
- package/schemas/diary-entry.schema.json +80 -80
- package/scripts/benchmark-memoria.js +167 -167
- package/scripts/comandos/skills.js +251 -2
- package/scripts/configurar-branch-protection.js +418 -418
- package/scripts/detectar-aprendizajes-duplicados.js +151 -151
- package/scripts/field-report.js +199 -199
- package/scripts/generar-checklists-consolidados.js +273 -273
- package/scripts/generar-inventario.js +420 -420
- package/scripts/generar-matriz-lenguajes.js +271 -271
- package/scripts/lib/artefactos-python.js +43 -43
- package/scripts/lib/benchmark-metrics.js +160 -160
- package/scripts/lib/budget-enforcer.js +252 -252
- package/scripts/lib/configurar-ci.js +380 -380
- package/scripts/lib/contadores-inventario.js +217 -217
- package/scripts/lib/detectar-stack-detallado.js +307 -307
- package/scripts/lib/diary-entry.js +234 -234
- package/scripts/lib/eval-metrics-store.js +218 -218
- package/scripts/lib/eval-quality.js +171 -171
- package/scripts/lib/eval-schemas.js +144 -144
- package/scripts/lib/eval-self-correct.js +106 -106
- package/scripts/lib/eval-validator.js +185 -185
- package/scripts/lib/jaccard-similarity.js +98 -98
- package/scripts/lib/longmemeval-runner.js +125 -125
- package/scripts/lib/npm-version.js +261 -261
- package/scripts/lib/paquetes-conocidos.js +50 -50
- package/scripts/lib/prompt-builder.js +264 -264
- package/scripts/lib/rrf-fusion.js +175 -175
- package/scripts/lib/scoring-instintos.js +277 -277
- package/scripts/lib/semantic-search.js +252 -252
- package/scripts/limpiar-artefactos-python.js +131 -131
- package/scripts/mcp-server/README.md +128 -128
- package/scripts/mcp-server/handlers.js +206 -206
- package/scripts/migrar-csv-a-array.js +168 -168
- package/scripts/migrar-fase-dominio.js +201 -201
- package/scripts/publicar.js +511 -511
- package/scripts/run-eval.js +141 -141
- package/scripts/validar-manifest.js +195 -195
- package/scripts/validar-userland-vacio.js +110 -110
- package/scripts/verificar-release.js +110 -0
|
@@ -1,12 +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.2.0"
|
|
5
5
|
evolved: true
|
|
6
|
-
evolved-from: "1.1.
|
|
7
|
-
evolved-at: "2026-05-
|
|
6
|
+
evolved-from: "1.1.1"
|
|
7
|
+
evolved-at: "2026-05-12"
|
|
8
8
|
evolved-by: "aprender"
|
|
9
|
-
evolved-note: "L-
|
|
9
|
+
evolved-note: "Backport L-138 SIGM: Sidebar/menu con RBAC debe ocultar secciones cuyos items quedan todos filtrados; previo L-105 setState in useEffect"
|
|
10
10
|
herramientasPermitidas: [Read]
|
|
11
11
|
exclusiones:
|
|
12
12
|
- "No cargar para optimización de rendimiento React (memo, useMemo, useCallback, virtualización, code splitting) — para rendimiento cargar `react-optimizacion`."
|
|
@@ -158,6 +158,47 @@ useEffect(() => {
|
|
|
158
158
|
const filtrados = useMemo(() => usuarios.filter(u => u.activo), [usuarios]);
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
### Sidebar/menu con RBAC: ocultar secciones cuyos items quedan todos filtrados
|
|
162
|
+
|
|
163
|
+
**Problema** (L-138 SIGM 2026-05-12): un sidebar con secciones colapsables filtra items por permiso del usuario. Si un usuario sin el permiso requerido ve la sección con su header y chevron pero al expandirla aparece un `<ul>` vacío, el bug confunde — el usuario reporta "el menú no despliega nada", sin saber si es bug del sistema o falta data. Caso SIGM: sección "Ventanilla" tenía 1 item con permiso `CAJA:cobrar`; cuando ningún usuario tenía ese string literal (era `RECAUDACION:CAJA:cobrar`), todos los usuarios veían la sección vacía.
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
// MAL — header se renderiza aunque el <ul> quede vacío
|
|
167
|
+
{NAV_SECTIONS.map((section) => (
|
|
168
|
+
<Section key={section.title}>
|
|
169
|
+
<SectionHeader title={section.title} />
|
|
170
|
+
<ul>
|
|
171
|
+
{section.items
|
|
172
|
+
.filter((item) => !item.permiso || tienePermiso(item.permiso))
|
|
173
|
+
.map((item) => <NavItem key={item.href} {...item} />)}
|
|
174
|
+
</ul>
|
|
175
|
+
</Section>
|
|
176
|
+
))}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
// BIEN — filtrar items ANTES de decidir si renderizar la sección
|
|
181
|
+
{NAV_SECTIONS.map((section) => {
|
|
182
|
+
const itemsVisibles = section.items.filter(
|
|
183
|
+
(item) => !item.permiso || tienePermiso(item.permiso),
|
|
184
|
+
)
|
|
185
|
+
if (itemsVisibles.length === 0) return null // ← omitir sección entera
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<Section key={section.title}>
|
|
189
|
+
<SectionHeader title={section.title} />
|
|
190
|
+
<ul>
|
|
191
|
+
{itemsVisibles.map((item) => <NavItem key={item.href} {...item} />)}
|
|
192
|
+
</ul>
|
|
193
|
+
</Section>
|
|
194
|
+
)
|
|
195
|
+
})}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Aplica también a**: tabs, breadcrumbs, dropdowns de filtros, paneles de configuración con secciones por permiso. Patrón: cualquier UI que agrupa items en secciones donde los items pueden filtrarse por RBAC.
|
|
199
|
+
|
|
200
|
+
**Test obligatorio**: cuando el mock de `useAuth` NO incluye los permisos de una sección, esa sección NO debe renderizarse en el DOM (`expect(queryByText('NombreSección')).not.toBeInTheDocument()`).
|
|
201
|
+
|
|
161
202
|
```tsx
|
|
162
203
|
// MAL: fetch en Client Component cuando podria ser RSC
|
|
163
204
|
useEffect(() => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
{
|
|
2
|
-
"SKILL.md": {
|
|
3
|
-
"evolved": true,
|
|
4
|
-
"evolvedFrom": "1.0.1",
|
|
5
|
-
"evolvedAt": "2026-05-02",
|
|
6
|
-
"evolvedBy": "aprender",
|
|
7
|
-
"evolvedNote": "Sección nueva: publish a múltiples registries (republish-only + auth GitHub Packages)"
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"SKILL.md": {
|
|
3
|
+
"evolved": true,
|
|
4
|
+
"evolvedFrom": "1.0.1",
|
|
5
|
+
"evolvedAt": "2026-05-02",
|
|
6
|
+
"evolvedBy": "aprender",
|
|
7
|
+
"evolvedNote": "Sección nueva: publish a múltiples registries (republish-only + auth GitHub Packages)"
|
|
8
|
+
}
|
|
9
9
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tdd-workflow
|
|
3
3
|
description: Flujo completo de Test-Driven Development. Ciclo RED (el test falla) → GREEN (implementación mínima) → REFACTOR (limpieza). Incluye cobertura mínima obligatoria, tests de frontera, factories, fixtures y estrategias para diferentes tipos de código (APIs, services, componentes Angular).
|
|
4
|
-
version: "1.0.
|
|
4
|
+
version: "1.0.2"
|
|
5
5
|
evolved: true
|
|
6
|
-
evolved-from: "1.0.
|
|
7
|
-
evolved-at: "2026-05-
|
|
6
|
+
evolved-from: "1.0.1"
|
|
7
|
+
evolved-at: "2026-05-14"
|
|
8
8
|
evolved-by: "aprender"
|
|
9
|
-
evolved-note: "
|
|
9
|
+
evolved-note: "Patrón reloj inyectable (parámetro `ahora` con default Date.now()) para tests deterministas sin freezegun/jest.useFakeTimers — validado en 3 módulos sesión webhook Opción C"
|
|
10
10
|
herramientasPermitidas: [Read, Bash]
|
|
11
11
|
evolvable: true # default para skill estandar
|
|
12
12
|
exclusiones:
|
|
@@ -297,4 +297,36 @@ pytest --cov=src/services --cov-fail-under=90
|
|
|
297
297
|
|
|
298
298
|
**`db_session.rollback()` en el fixture de pytest-asyncio no deshace los datos insertados por `db.flush()` dentro de la función testeada cuando la sesión usa `autocommit=True` implícito por configuración del engine**: algunos proyectos configuran `AsyncEngine` con `isolation_level="AUTOCOMMIT"` para compatibilidad con operaciones DDL; en ese contexto, cada `flush()` hace commit inmediatamente y el `rollback()` del fixture no puede deshacer esos cambios. Causa: `AUTOCOMMIT` en PostgreSQL significa que no hay transacción activa que se pueda revertir. Fix: verificar que el engine de tests NO use `isolation_level="AUTOCOMMIT"` (la configuración debe ser solo para el engine de migraciones Alembic, no para el de la app). Para tests que necesitan AUTOCOMMIT por alguna razón, usar una BD de test separada que se trunca con `TRUNCATE ... RESTART IDENTITY CASCADE` en el teardown del fixture.
|
|
299
299
|
|
|
300
|
+
**Reloj inyectable como parámetro `ahora` habilita tests deterministas sin `freezegun`, `jest.useFakeTimers()` ni `sinon.useFakeTimers()`** [PATRÓN VALIDADO en SWL Opción C webhook]: cuando una API depende del tiempo (rate-limit con bucket que se rellena, dedup con ventana de retención, cache con TTL, schedulers), recibir el timestamp por parámetro en lugar de llamar `Date.now()` internamente permite que los tests pasen 1000 segundos en 0 ms reales. Diseño: `metodo(arg1, arg2, ahora = Date.now())` — producción no cambia (llamadas siguen siendo `obj.consumir(1)`), tests pasan `ahora` explícito (`obj.consumir(1, T0 + 5000)`). Validado en 3 módulos esta sesión: `rate-limit-ip.js` (40+ tests bucket refill, capacidad, cleanup), `webhook-dedup.js` (ventana de retención, rotación idempotente), helpers internos de `webhook-server.js`. Ningún test usa `sleep`, ningún test es flaky, ningún test mockea `Date`. Aplicable a JS/TS y a Python (`def consumir(self, tokens, ahora=None)` con `ahora = ahora or datetime.now(UTC)` al inicio).
|
|
301
|
+
|
|
302
|
+
```js
|
|
303
|
+
// MAL — test no-determinista, requiere sleep o mock global
|
|
304
|
+
class Bucket {
|
|
305
|
+
consumir(n) {
|
|
306
|
+
const ahora = Date.now(); // ← imposible de controlar desde el test
|
|
307
|
+
this._rellenar(ahora);
|
|
308
|
+
if (this.tokens >= n) { this.tokens -= n; return true; }
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// BIEN — reloj inyectable, test determinista
|
|
314
|
+
class Bucket {
|
|
315
|
+
consumir(n, ahora = Date.now()) { // ← default en producción, inyectable en test
|
|
316
|
+
this._rellenar(ahora);
|
|
317
|
+
if (this.tokens >= n) { this.tokens -= n; return true; }
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// En el test:
|
|
323
|
+
const T0 = 1700000000000;
|
|
324
|
+
const b = new Bucket(10, 1, T0);
|
|
325
|
+
for (let i = 0; i < 10; i++) b.consumir(1, T0); // saturar
|
|
326
|
+
assert.equal(b.consumir(1, T0), false); // sin refill aún
|
|
327
|
+
assert.equal(b.consumir(5, T0 + 5000), true); // 5 seg después: 5 tokens
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Aplica también a tests de clock skew (tiempo retrocede por NTP): pasar `T0 - 1000` y validar que la lógica no rompe. Origen: rate-limit-ip.js + webhook-dedup.js sesión 2026-05-13.
|
|
331
|
+
|
|
300
332
|
**Tests nombrados por feature (`test_emitir_factura_exitosa`) pierden poder regresivo; nombrados por causa raíz (`test_repository_no_usa_columna_inexistente_p_monto`) detectan regresiones específicas sin reproducción manual** [CONFIRMADO en SIGM Opción C F1.4]: cuando se descubre un bug por una causa raíz concreta (typo en nombre de columna SQL, omisión de `selectinload`, mock que devuelve dict en vez de objeto, schema obsoleto), el test de regresión que se escribe debe llevar el nombre de la causa, no del feature afectado. Caso real: durante F1.4 de SIGM, el repository de pagos referenciaba `p.monto` cuando la columna se llamaba `p.monto_pagado`; el test escrito como `test_repository_no_usa_columna_inexistente_p_monto` falló inmediatamente en la siguiente sesión cuando otro agente reintrodujo el typo, sin necesidad de reproducir el escenario de negocio (emitir cobro real, verificar respuesta). Causa: los nombres orientados a feature (`test_pago_exitoso`) son ambiguos sobre QUÉ falla — si el test falla, el desarrollador debe diagnosticar; los nombres orientados a causa raíz (`test_X_no_usa_Y`, `test_query_incluye_selectinload_Z`, `test_service_devuelve_dict_no_objeto`) son auto-diagnósticos. Fix: para cada bug que cueste >30 min diagnosticar, escribir UN test adicional cuyo nombre describa la condición técnica violada, no el escenario de negocio. Convención: `test_<componente>_<condicion_tecnica>` o `test_<componente>_no_<anti_patron>`. Estos tests son tu segunda línea de defensa contra regresiones de la misma causa raíz, complementarios a los tests de comportamiento.
|