@saulwade/swl-ses 2.2.1 → 2.2.4
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 +3 -3
- package/README.md +1 -1
- package/agentes/arquitecto-swl.md +1 -1
- package/agentes/auto-evolucion-swl.md +908 -908
- package/agentes/backend-csharp-swl.md +1 -1
- package/agentes/backend-go-swl.md +1 -1
- package/agentes/backend-java-swl.md +1 -1
- package/agentes/backend-rust-swl.md +1 -1
- package/agentes/evals/orquestador-swl.evals.json +1 -1
- package/agentes/implementador-swl.md +2 -2
- package/agentes/llm-apps-swl.md +1 -1
- package/agentes/orquestador-swl.md +7 -7
- package/agentes/pagos-swl.md +1 -1
- package/agentes/perfilador-usuario-swl.md +321 -321
- package/agentes/planificador-swl.md +1 -1
- package/agentes/producto-prd-swl.md +1 -1
- package/agentes/revisor-seguridad-swl.md +1 -1
- package/agentes/sre-swl.md +1 -1
- package/bin/swl-mcp-server.js +1 -1
- package/comandos/swl/release.md +15 -0
- package/comandos/swl/verificar.md +817 -817
- package/habilidades/compactacion-contexto/SKILL.md +3 -3
- package/habilidades/context-builder/SKILL.md +4 -4
- package/habilidades/control-profundidad/SKILL.md +5 -5
- package/habilidades/guardrail-semantico/SKILL.md +1 -1
- package/habilidades/harness-claude-code/SKILL.md +305 -305
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +1 -1
- package/habilidades/prompt-engineering/SKILL.md +5 -5
- package/habilidades/release-semver/SKILL.md +4 -1
- package/habilidades/workflow-claude-code/SKILL.md +6 -6
- package/hooks/lib/context-builder.js +2 -2
- package/hooks/lib/etapa-perfil-usuario.js +1 -1
- package/hooks/lib/model-router.js +1 -1
- package/hooks/lib/token-estimator.js +2 -0
- package/hooks/linea-estado.js +7 -5
- package/hooks/resumen-sesion.js +4 -4
- package/llms.txt +1 -1
- package/manifiestos/canonical-hashes.json +1637 -656
- package/manifiestos/skills-lock.json +1282 -1282
- package/package.json +93 -93
- package/plugin.json +371 -371
- package/reglas/git-coauthor.md +100 -100
- package/reglas/pruebas.md +15 -0
- package/schemas/agent-frontmatter.schema.json +294 -294
- package/scripts/doctor.js +13 -0
- package/scripts/instalador.js +22 -9
- package/scripts/lib/audit-evolved.js +7 -2
- package/scripts/lib/claude-sessions.js +1 -0
- package/scripts/lib/manifiestos.js +1 -1
- package/scripts/lib/tool-cost-analyzer.js +1 -0
- package/scripts/publicar.js +76 -90
- package/scripts/remediar-evolved-instaladas.js +6 -3
|
@@ -3,7 +3,7 @@ name: prompt-engineering
|
|
|
3
3
|
description: >
|
|
4
4
|
Diseño y optimización de prompts para LLMs: chain-of-thought, few-shot,
|
|
5
5
|
system prompts, structured outputs y técnicas de evaluación. Incluye guía
|
|
6
|
-
para Claude Opus 4.
|
|
6
|
+
para Claude Opus 4.8 y su patrón de instrucciones literales vs inferidas.
|
|
7
7
|
Cargar cuando se diseñen system prompts, se optimice la calidad de
|
|
8
8
|
respuestas LLM, se implemente prompt chaining, o se evalúe la efectividad
|
|
9
9
|
de prompts.
|
|
@@ -26,15 +26,15 @@ exclusiones:
|
|
|
26
26
|
- La tarea es fine-tuning o ajuste de pesos de un modelo: usar documentación del proveedor directamente.
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
## Prompts literales vs inferidos (Opus 4.
|
|
29
|
+
## Prompts literales vs inferidos (Opus 4.8)
|
|
30
30
|
|
|
31
|
-
Desde Claude Opus 4.
|
|
31
|
+
Desde Claude Opus 4.8 (abril 2026), Anthropic cambió cómo el modelo interpreta
|
|
32
32
|
instrucciones ambiguas:
|
|
33
33
|
|
|
34
34
|
- **Opus 4.6 y anteriores**: rellenaban ambigüedades con inferencia razonable.
|
|
35
35
|
Un prompt como "agrega validación al formulario" generaba validación completa
|
|
36
36
|
con reglas de dominio típicas.
|
|
37
|
-
- **Opus 4.
|
|
37
|
+
- **Opus 4.8**: sigue instrucciones de forma más literal. El mismo prompt ahora
|
|
38
38
|
genera validación mínima (o pregunta qué validar) porque la instrucción
|
|
39
39
|
literal no especifica qué campos ni qué reglas.
|
|
40
40
|
|
|
@@ -73,7 +73,7 @@ validación fallando."""
|
|
|
73
73
|
|
|
74
74
|
### Effort levels vs verbosidad
|
|
75
75
|
|
|
76
|
-
Opus 4.
|
|
76
|
+
Opus 4.8 no mezcla "cuánto pensar" con "cuán verboso ser". Son ejes distintos:
|
|
77
77
|
|
|
78
78
|
| Eje | Control |
|
|
79
79
|
|-----|---------|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release-semver
|
|
3
3
|
description: Versionado semántico (SemVer). Cuándo bumpar major/minor/patch, changelogs convencionales, estrategia de tags y proceso de release completo.
|
|
4
|
-
version: "1.0.
|
|
4
|
+
version: "1.0.3"
|
|
5
5
|
herramientasPermitidas: [Read, Bash]
|
|
6
6
|
exclusiones:
|
|
7
7
|
- "No cargar para versionar el sistema SWL — el bump de versión de swl-ses sigue el checklist de 15 ubicaciones documentado en `/swl:release`; este skill cubre SemVer general para proyectos de usuario, no el proceso interno de release del sistema."
|
|
@@ -325,3 +325,6 @@ de token inválido.
|
|
|
325
325
|
- **Changelog generado con `git cliff` sin configuración personalizada incluye commits de chore y docs**: el CHANGELOG.md resultante tiene 80% de entradas de limpieza que no interesan a los consumidores. Causa: `git cliff` sin `.cliff.toml` incluye todos los tipos de commit. Solución: crear `.cliff.toml` en el repo con la sección `[git]` filtrando solo `feat`, `fix`, `perf` y `BREAKING CHANGE` para el changelog de release público.
|
|
326
326
|
- **Rama `release/2.1.0` mergeada a `main` pero no a `develop`**: el próximo desarrollo parte de `develop` sin incluir los commits del release, generando conflictos en la siguiente rama de feature. Causa: el Paso 4 requiere merge a ambas ramas pero se omite el merge a `develop` por considerar que el release ya está en `main`. Solución: el proceso de release de 4 pasos del skill requiere merge a `main` Y a `develop` antes de eliminar la rama de release — ambos merges son parte del mismo paso atómico.
|
|
327
327
|
- **`npx <paquete> <comando>` sin `@latest` usa caché stale indefinidamente**: tras publicar una nueva versión, `npx swl-ses doctor` sigue ejecutando la primera versión que el usuario cacheó (por ejemplo v5.7.0 cuando ya hay v5.10.3 instalada). Causa: npx resuelve a la primera versión disponible y la cachea; sin `@latest` nunca vuelve a consultar el registry. Solución: SIEMPRE usar `npx paquete@latest <comando>` en mensajes post-install, hooks de alerta de nueva versión, docs del README, ejemplos en CHANGELOG y scripts de inicialización. Nunca `npx paquete <comando>` desnudo — incluso si el paquete acaba de publicarse; el caché de un desarrollador vecino puede tener una versión anterior desde hace meses. Un bump sin `@latest` en los mensajes post-install perpetúa el problema para todos los usuarios nuevos.
|
|
328
|
+
- **`npm pack --ignore-scripts` mete `__pycache__/*.pyc` (o cualquier artefacto del `prepack`) en el tarball publicado**: al saltar `--ignore-scripts` el lifecycle `prepack`, se omite la limpieza de artefactos que suele ser el ÚNICO filtro efectivo — un `.npmignore` con `**/*.pyc` NO los excluye de forma fiable cuando `package.json#files` es un allowlist (los paths del allowlist se incluyen y `.npmignore` no los poda). Causa: usar `--ignore-scripts` para "acelerar" un `npm pack`/publish manual. Solución: usar `npm pack` a secas — el `prepack` (rápido) limpia el árbol; `prepublishOnly` (lento, tests) solo corre en `npm publish`, NO en `pack`, así que no hay nada que "ahorrar". Señal de alerta: un salto inesperado en `total files` del tarball (p.ej. +1) suele ser un artefacto colado.
|
|
329
|
+
- **Log de release con `createWriteStream` queda VACÍO al `process.exit()`**: un script de publicación que abre el log con `fs.createWriteStream` (async) y termina con `process.exit(code)` no alcanza a vaciar el buffer del stream a disco antes de que el proceso muera — justo cuando más se necesita el log para diagnosticar el fallo. Causa: asumir que `stream.end()` antes de `process.exit()` fuerza el flush (es asíncrono, no lo garantiza). Solución: para logs que DEBEN sobrevivir un `exit` inmediato, usar escritura SÍNCRONA: `fs.writeFileSync` (header) + `fs.appendFileSync` (cada chunk), que vacían en cada llamada.
|
|
330
|
+
- **Forzar prompt de OTP TOTP rompe a usuarios con passkey/WebAuthn**: un wrapper de publish que intercepta el `EOTP` de npm y pide un código de 6 dígitos asume 2FA tipo TOTP; si la cuenta usa passkey (flujo web "abrir URL y seleccionar la llave") el prompt es un callejón sin salida. Causa: tratar `EOTP` como sinónimo de "pedir TOTP". Solución: ante `EOTP` con TTY, reintentar el `npm publish` con **stdio heredado** (`stdio: 'inherit'`) y dejar que npm conduzca su 2FA NATIVO — soporta TOTP Y passkey según la cuenta. Alternativa permanente sin 2FA: token **Automation** (no "Publish", que sí exige 2FA).
|
|
@@ -3,7 +3,7 @@ name: workflow-claude-code
|
|
|
3
3
|
description: >
|
|
4
4
|
Patrones de flujo de trabajo diario con Claude Code: gestión de sesiones,
|
|
5
5
|
atajos de teclado, Plan Mode, feature-per-session, gestión de contexto,
|
|
6
|
-
jerarquía de memoria, handoff multi-sesión, niveles de esfuerzo de Opus 4.
|
|
6
|
+
jerarquía de memoria, handoff multi-sesión, niveles de esfuerzo de Opus 4.8
|
|
7
7
|
(high/xhigh/max) y el patrón de delegación. Cargar cuando el usuario pregunte
|
|
8
8
|
cómo usar Claude Code eficientemente, cuando necesite optimizar su flujo de
|
|
9
9
|
trabajo, o cuando inicie un proyecto nuevo. NO cargar para estructura de
|
|
@@ -189,9 +189,9 @@ Para ESTRUCTURA de proyecto, usar `estructura-proyecto-claude`.
|
|
|
189
189
|
|
|
190
190
|
---
|
|
191
191
|
|
|
192
|
-
## Patrón de delegación con Opus 4.
|
|
192
|
+
## Patrón de delegación con Opus 4.8 (desde abril 2026)
|
|
193
193
|
|
|
194
|
-
Opus 4.
|
|
194
|
+
Opus 4.8 introduce un shift operativo importante: **rinde mejor tratado como un
|
|
195
195
|
ingeniero al que delegas, no como un pair programmer al que guías línea por línea**.
|
|
196
196
|
Fuente: https://claude.com/blog/best-practices-for-using-claude-opus-4-7-with-claude-code
|
|
197
197
|
|
|
@@ -228,7 +228,7 @@ el modelo decide dinámicamente cuánto razonar según la tarea.
|
|
|
228
228
|
|
|
229
229
|
### Sub-agentes: paralelismo explícito
|
|
230
230
|
|
|
231
|
-
Opus 4.
|
|
231
|
+
Opus 4.8 usa menos sub-agentes por defecto que 4.6. Si una tarea se beneficia
|
|
232
232
|
de ejecución paralela, declararlo en el prompt:
|
|
233
233
|
|
|
234
234
|
- "Ejecuta estos 3 análisis en paralelo" > confiar en que lo decidirá solo.
|
|
@@ -236,7 +236,7 @@ de ejecución paralela, declararlo en el prompt:
|
|
|
236
236
|
|
|
237
237
|
### Instrucciones literales
|
|
238
238
|
|
|
239
|
-
Opus 4.
|
|
239
|
+
Opus 4.8 interpreta instrucciones de forma más literal. Los prompts ambiguos
|
|
240
240
|
que 4.6 resolvía por inferencia ahora se ejecutan al pie de la letra. Invertir
|
|
241
241
|
tiempo en eliminar ambigüedad al inicio ahorra iteraciones.
|
|
242
242
|
|
|
@@ -257,4 +257,4 @@ y quick reference completa, ver [recursos/referencia-completa.md](recursos/refer
|
|
|
257
257
|
- **Sesión de >40 turnos sin compactar**: el agente no monitorea el conteo de turnos y continúa trabajando hasta que Claude empieza a "olvidar" decisiones tomadas temprano en la sesión. Causa: no se aplica la señal de context rot (40 turnos). Solución: al llegar a 40 turnos, ejecutar `/swl:compactar` antes de la siguiente tarea grande — no esperar a que la degradación sea visible en la calidad del output.
|
|
258
258
|
- **CLAUDE.md superando 200 líneas sin subdirectorios**: el proyecto crece y todo el contexto se acumula en el CLAUDE.md raíz, incrementando la carga base de contexto de cada conversación. Causa: no se crean CLAUDE.md de subdirectorio para módulos como `backend/` o `frontend/`. Solución: extraer convenciones específicas de módulo a su propio `<directorio>/CLAUDE.md`; el CLAUDE.md raíz mantiene solo lo global.
|
|
259
259
|
- **Auto Accept Mode activado en operaciones destructivas**: el usuario activa `Shift+Tab` para acelerar trabajo y olvida cambiarlo antes de un deploy o borrado de archivos. Causa: el modo no tiene contexto de operación. Solución: volver a Default Mode explícitamente antes de operaciones irreversibles (`Shift+Tab` de vuelta) — Auto Accept es para generación de código, no para operaciones con blast radius alto.
|
|
260
|
-
- **Tokenizer 4.7 subestimado en presupuesto de contexto**: el mismo CLAUDE.md que ocupaba el 30% del contexto en Opus 4.6 ocupa hasta 40% en 4.7 debido al tokenizer más granular. Causa: el umbral de compactación no se recalibró al migrar de modelo. Solución: con Opus 4.
|
|
260
|
+
- **Tokenizer 4.7 subestimado en presupuesto de contexto**: el mismo CLAUDE.md que ocupaba el 30% del contexto en Opus 4.6 ocupa hasta 40% en 4.7 debido al tokenizer más granular. Causa: el umbral de compactación no se recalibró al migrar de modelo. Solución: con Opus 4.8, bajar el umbral de compactación de 70% a 50% tal como indica el skill `compactacion-contexto`.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const path = require('path');
|
|
21
21
|
|
|
22
|
-
const DEFAULT_TOKEN_BUDGET = 2500; // Recalibrado para Opus 4.
|
|
22
|
+
const DEFAULT_TOKEN_BUDGET = 2500; // Recalibrado para Opus 4.8 (tokenizer 1.0-1.35x vs 4.6)
|
|
23
23
|
const CHARS_POR_TOKEN = 4; // Heuristica para espanol
|
|
24
24
|
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
@@ -211,7 +211,7 @@ function buildAprendizajes(baseDir, max, budgetRestante) {
|
|
|
211
211
|
*
|
|
212
212
|
* @param {string} baseDir - Directorio raiz del proyecto.
|
|
213
213
|
* @param {object} [opciones]
|
|
214
|
-
* @param {number} [opciones.tokenBudget=2500] - Presupuesto de tokens (default 2500 — recalibrado para Opus 4.
|
|
214
|
+
* @param {number} [opciones.tokenBudget=2500] - Presupuesto de tokens (default 2500 — recalibrado para Opus 4.8).
|
|
215
215
|
* @param {number} [opciones.maxAprendizajes=5] - Max aprendizajes a incluir.
|
|
216
216
|
* @param {number} [opciones.maxInstintos=5] - Max instintos a incluir.
|
|
217
217
|
* @returns {{ contexto: string, tokensUsados: number, seccionesTruncadas: string[] }}
|
|
@@ -251,7 +251,7 @@ function ejecutar(inputRaw) {
|
|
|
251
251
|
// cada sesión.
|
|
252
252
|
const señalesKw = detectarKeywords(textoUsuario)
|
|
253
253
|
.map(s => {
|
|
254
|
-
const r = scanInjection(s.snippet, '
|
|
254
|
+
const r = scanInjection(s.snippet, 'user-profile/dirty.json');
|
|
255
255
|
return { ...s, _scan: r };
|
|
256
256
|
})
|
|
257
257
|
.filter(s => {
|
|
@@ -87,6 +87,7 @@ const COSTO_DEFAULT_POR_MILLON = 3.0;
|
|
|
87
87
|
*/
|
|
88
88
|
const PRICING_CANONICO = {
|
|
89
89
|
// Anthropic — precios por 1M tokens (nombres canónicos)
|
|
90
|
+
'claude-opus-4-8': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
90
91
|
'claude-opus-4-7': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
91
92
|
'claude-opus-4-6': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
92
93
|
'claude-opus-4-5': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
@@ -97,6 +98,7 @@ const PRICING_CANONICO = {
|
|
|
97
98
|
'claude-haiku-4-5': { input: 0.80, output: 4.00, cacheRead: 0.08, cacheWrite: 1.00 },
|
|
98
99
|
'claude-3-5-haiku': { input: 0.80, output: 4.00, cacheRead: 0.08, cacheWrite: 1.00 },
|
|
99
100
|
// Aliases con prefijo anthropic/ (compatibilidad con mission-control y gateways)
|
|
101
|
+
'anthropic/claude-opus-4-8': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
100
102
|
'anthropic/claude-opus-4-7': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
101
103
|
'anthropic/claude-opus-4-6': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
|
102
104
|
'anthropic/claude-opus-4-5': { input: 15.00, output: 75.00, cacheRead: 1.50, cacheWrite: 18.75 },
|
package/hooks/linea-estado.js
CHANGED
|
@@ -43,15 +43,17 @@ const TOKENS_MAXIMOS_DEFAULT = 200_000;
|
|
|
43
43
|
*
|
|
44
44
|
* IMPORTANTE: las claves son prefijos del `model_id` reportado por Claude Code
|
|
45
45
|
* en el evento del hook. La detección hace `modelId.includes(prefijo)` en orden;
|
|
46
|
-
* los prefijos más específicos van primero para que `claude-opus-4-
|
|
46
|
+
* los prefijos más específicos van primero para que `claude-opus-4-8` no
|
|
47
47
|
* matchee accidentalmente con la entrada genérica `claude-opus`.
|
|
48
48
|
*
|
|
49
|
-
* Si el `model_id` contiene el sufijo `[1m]` (ej: `claude-opus-4-
|
|
49
|
+
* Si el `model_id` contiene el sufijo `[1m]` (ej: `claude-opus-4-8[1m]`), el
|
|
50
50
|
* techo se fuerza a 1M independientemente del modelo base — Anthropic usa
|
|
51
51
|
* ese sufijo para indicar la variante de 1M context.
|
|
52
52
|
*/
|
|
53
53
|
const TECHOS_POR_MODELO = {
|
|
54
|
-
// Opus 4.
|
|
54
|
+
// Opus 4.8 — variante de 1M context (la actual por defecto)
|
|
55
|
+
'claude-opus-4-8': 1_000_000,
|
|
56
|
+
// Opus 4.7 — variante de 1M context (histórica)
|
|
55
57
|
'claude-opus-4-7': 1_000_000,
|
|
56
58
|
// Resto de modelos modernos: 200k context
|
|
57
59
|
'claude-opus-4-6': 200_000,
|
|
@@ -84,7 +86,7 @@ const ETIQUETAS_MODELO = {
|
|
|
84
86
|
* 3. Default → TOKENS_MAXIMOS_DEFAULT (200k).
|
|
85
87
|
*
|
|
86
88
|
* @param {string} modelId - Identificador completo del modelo, posiblemente
|
|
87
|
-
* con sufijo de variante (ej: `claude-opus-4-
|
|
89
|
+
* con sufijo de variante (ej: `claude-opus-4-8[1m]`).
|
|
88
90
|
* @returns {number} Techo de tokens del contexto.
|
|
89
91
|
*/
|
|
90
92
|
function techoTokens(modelId) {
|
|
@@ -261,7 +263,7 @@ process.stdin.on('end', () => {
|
|
|
261
263
|
// Ruta del archivo bridge compartido entre hooks
|
|
262
264
|
const bridgePath = path.join(os.tmpdir(), `swl-ctx-${sessionId}.json`);
|
|
263
265
|
|
|
264
|
-
// Resolver techo según modelo (Opus 4.
|
|
266
|
+
// Resolver techo según modelo (Opus 4.8 con sufijo [1m] = 1M; resto 200k)
|
|
265
267
|
const techo = techoTokens(modelId);
|
|
266
268
|
|
|
267
269
|
// Calcular métricas
|
package/hooks/resumen-sesion.js
CHANGED
|
@@ -85,10 +85,10 @@ function hooksDisparados(sessionId) {
|
|
|
85
85
|
try {
|
|
86
86
|
const planningDir = path.join(process.cwd(), '.planning');
|
|
87
87
|
const jsonlCandidatos = [
|
|
88
|
-
['
|
|
89
|
-
['auto-
|
|
90
|
-
['
|
|
91
|
-
['
|
|
88
|
+
['evolution/nudges.jsonl', 'nudge-tracker'],
|
|
89
|
+
['auto-evolution/agentes.jsonl', 'auto-evolucion'],
|
|
90
|
+
['user-profile/dirty.json', 'actualizar-perfil-usuario'],
|
|
91
|
+
['evolution/metricas.json', 'metricas-evolucion'],
|
|
92
92
|
];
|
|
93
93
|
for (const [rel, nombre] of jsonlCandidatos) {
|
|
94
94
|
const p = path.join(planningDir, rel);
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# swl-ses (@saulwade/swl-ses)
|
|
2
2
|
|
|
3
|
-
> Sistema de ingeniería de software auto-evolutivo multi-runtime polyglot (SDLC completo), distribuido como paquete npm y plugin de Claude Code. 60 agentes, 182 habilidades, 44 comandos, 37 reglas base y 48 hooks. Soporta 11 lenguajes y 7 runtimes (Claude Code, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot). Versión 2.2.
|
|
3
|
+
> Sistema de ingeniería de software auto-evolutivo multi-runtime polyglot (SDLC completo), distribuido como paquete npm y plugin de Claude Code. 60 agentes, 182 habilidades, 44 comandos, 37 reglas base y 48 hooks. Soporta 11 lenguajes y 7 runtimes (Claude Code, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot). Versión 2.2.4.
|
|
4
4
|
|
|
5
5
|
Archivo generado por `node scripts/generar-inventario.js` — no editar a mano. Las cifras se sincronizan con INVENTARIO.md en cada regeneración.
|
|
6
6
|
|