@saulwade/swl-ses 2.6.0 → 2.8.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 +209 -197
- package/README.md +647 -600
- package/agentes/accesibilidad-wcag-swl.md +690 -690
- package/agentes/arquitecto-swl.md +267 -267
- package/agentes/auto-evolucion-swl.md +932 -932
- package/agentes/backend-csharp-swl.md +420 -420
- package/agentes/backend-go-swl.md +390 -390
- package/agentes/backend-java-swl.md +281 -281
- package/agentes/backend-rust-swl.md +364 -364
- package/agentes/backend-workers-swl.md +482 -482
- package/agentes/cloud-infra-swl.md +509 -509
- package/agentes/consolidador-swl.md +541 -541
- package/agentes/depurador-swl.md +352 -352
- package/agentes/devops-ci-swl.md +400 -400
- package/agentes/disenador-ui-swl.md +569 -569
- package/agentes/documentador-swl.md +345 -345
- package/agentes/frontend-angular-swl.md +621 -621
- package/agentes/frontend-css-swl.md +716 -716
- package/agentes/frontend-react-swl.md +692 -692
- package/agentes/frontend-swl.md +496 -496
- package/agentes/frontend-tailwind-swl.md +826 -826
- package/agentes/investigador-swl.md +432 -432
- package/agentes/investigador-ux-swl.md +505 -505
- package/agentes/migrador-swl.md +442 -442
- package/agentes/mobile-android-swl.md +511 -511
- package/agentes/mobile-cross-swl.md +541 -541
- package/agentes/mobile-ios-swl.md +502 -502
- package/agentes/mobile-testing-swl.md +302 -302
- package/agentes/nemesis-auditor-swl.md +285 -285
- package/agentes/observabilidad-swl.md +438 -438
- package/agentes/pagos-swl.md +310 -310
- package/agentes/perfilador-usuario-swl.md +321 -321
- package/agentes/planificador-swl.md +399 -399
- package/agentes/producto-prd-swl.md +589 -589
- package/agentes/red-team-swl.md +218 -218
- package/agentes/release-manager-swl.md +590 -590
- package/agentes/rendimiento-swl.md +713 -713
- package/agentes/revisor-angular-swl.md +278 -278
- package/agentes/revisor-csharp-swl.md +264 -264
- package/agentes/revisor-go-swl.md +259 -259
- package/agentes/revisor-java-swl.md +257 -257
- package/agentes/revisor-kotlin-swl.md +273 -273
- package/agentes/revisor-nextjs-swl.md +281 -281
- package/agentes/revisor-php-swl.md +271 -271
- package/agentes/revisor-react-swl.md +278 -278
- package/agentes/revisor-rust-swl.md +346 -346
- package/agentes/revisor-seguridad-swl.md +399 -399
- package/agentes/revisor-swift-swl.md +268 -268
- package/agentes/revisor-typescript-swl.md +346 -346
- package/agentes/tdd-qa-swl.md +393 -393
- package/bin/swl-ses.js +10 -0
- package/comandos/swl/actualizar.md +174 -174
- package/comandos/swl/adoptar-proyecto.md +265 -265
- package/comandos/swl/aprender.md +836 -836
- package/comandos/swl/aprobar-plan.md +146 -146
- package/comandos/swl/auditar-deps.md +134 -134
- package/comandos/swl/autoresearch.md +264 -264
- package/comandos/swl/ayuda.md +224 -224
- package/comandos/swl/brainstorm.md +52 -51
- package/comandos/swl/checkpoint.md +325 -325
- package/comandos/swl/claudemd.md +234 -234
- package/comandos/swl/compactar.md +310 -310
- package/comandos/swl/configurar-ci.md +235 -235
- package/comandos/swl/contexto.md +110 -110
- package/comandos/swl/crear-skill.md +292 -292
- package/comandos/swl/cron.md +194 -194
- package/comandos/swl/deuda-codigo.md +97 -97
- package/comandos/swl/discutir-fase.md +169 -169
- package/comandos/swl/ejecutar-fase.md +233 -233
- package/comandos/swl/evaluar-skill.md +520 -520
- package/comandos/swl/evolucion-continua.md +73 -73
- package/comandos/swl/evolucionar.md +267 -267
- package/comandos/swl/exportar-vault.md +583 -583
- package/comandos/swl/fix.md +118 -118
- package/comandos/swl/gateway.md +158 -158
- package/comandos/swl/inbox.md +116 -116
- package/comandos/swl/instalar.md +220 -220
- package/comandos/swl/instintos.md +86 -86
- package/comandos/swl/mapear-codebase.md +312 -312
- package/comandos/swl/mcp-status.md +176 -175
- package/comandos/swl/modelo.md +100 -100
- package/comandos/swl/nemesis.md +433 -433
- package/comandos/swl/notificaciones.md +299 -299
- package/comandos/swl/nuevo-proyecto.md +251 -251
- package/comandos/swl/planear-fase.md +263 -263
- package/comandos/swl/plugins.md +256 -256
- package/comandos/swl/predecir.md +169 -169
- package/comandos/swl/reflect-skills.md +125 -125
- package/comandos/swl/release.md +450 -450
- package/comandos/swl/revisar-impacto.md +201 -201
- package/comandos/swl/revisar.md +330 -330
- package/comandos/swl/seguridad.md +189 -189
- package/comandos/swl/sesiones.md +200 -200
- package/comandos/swl/skill-search.md +113 -113
- package/comandos/swl/status.md +345 -345
- package/comandos/swl/verificar.md +817 -817
- package/comandos/swl/wiki.md +620 -620
- package/gateway/cron/jobs.example.json +12 -12
- package/gateway/lib/event-channel.js +191 -191
- package/habilidades/agent-deep-links/SKILL.md +148 -148
- package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -294
- package/habilidades/backend-async-postgres-testing/SKILL.md +216 -215
- package/habilidades/backend-error-design/SKILL.md +221 -221
- package/habilidades/backend-production-resilience/SKILL.md +288 -288
- package/habilidades/calidad-anti-patrones-universales/SKILL.md +105 -1
- package/habilidades/calidad-contract-testing/SKILL.md +165 -165
- package/habilidades/calidad-mutation-testing/SKILL.md +25 -1
- package/habilidades/changelog-generator/SKILL.md +174 -174
- package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
- package/habilidades/ci-cd-pipelines/SKILL.md +5 -1
- package/habilidades/compactacion-contexto/SKILL.md +2 -1
- package/habilidades/contenedores-docker/SKILL.md +4 -2
- package/habilidades/css-moderno/SKILL.md +7 -1
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
- package/habilidades/doubt-driven-review/SKILL.md +207 -207
- package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
- package/habilidades/drift-detection/SKILL.md +1 -1
- package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
- package/habilidades/extractor-de-aprendizajes/SKILL.md +12 -2
- package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
- package/habilidades/git-worktrees-paralelo/SKILL.md +19 -1
- package/habilidades/harness-claude-code/SKILL.md +315 -314
- package/habilidades/instalar-sistema/SKILL.md +227 -227
- package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
- package/habilidades/perfil-usuario/SKILL.md +200 -200
- package/habilidades/planear-fase/SKILL.md +358 -358
- package/habilidades/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
- package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
- package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
- package/habilidades/proceso-dynamic-workflows/SKILL.md +60 -0
- package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -65
- package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -65
- package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -147
- package/habilidades/proceso-intent-engineering/SKILL.md +269 -269
- package/habilidades/proceso-modular-split/SKILL.md +256 -256
- package/habilidades/release-semver/SKILL.md +2 -2
- package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
- package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -83
- package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -85
- package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -94
- package/habilidades/tdd-workflow/SKILL.md +749 -749
- package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
- package/hooks/agente-lifecycle.js +1 -1
- package/hooks/audit-trail.js +1 -1
- package/hooks/auto-consolidacion.js +1 -1
- package/hooks/calidad-pre-commit.js +159 -10
- package/hooks/captura-acciones-post.js +1 -1
- package/hooks/captura-acciones-session.js +1 -1
- package/hooks/captura-feedback-usuario.js +1 -1
- package/hooks/ciclo-evolucion-subagente.js +26 -26
- package/hooks/ciclo-evolucion.js +26 -26
- package/hooks/contexto-iteracion.js +1 -1
- package/hooks/degradacion-instintos.js +1 -1
- package/hooks/grafo-contexto.js +1 -1
- package/hooks/guardrail-modelo.js +1 -1
- package/hooks/inbox-aviso.js +1 -1
- package/hooks/inyeccion-contexto.js +1 -1
- package/hooks/lib/agent-matcher.js +1 -1
- package/hooks/lib/agent-routing.js +1 -1
- package/hooks/lib/auto-consolidator.js +335 -335
- package/hooks/lib/captura-acciones.js +1 -1
- package/hooks/lib/ciclo-evolucion.js +47 -47
- package/hooks/lib/deep-links.js +185 -185
- package/hooks/lib/error-classifier.js +308 -308
- package/hooks/lib/etapa-metricas.js +1 -1
- package/hooks/lib/evolution-tracker.js +1 -1
- package/hooks/lib/gateway-notify.js +193 -193
- package/hooks/lib/mcp-health.js +1 -1
- package/hooks/lib/notificacion-formato.js +92 -0
- package/hooks/lib/nudge-tracker.js +1 -1
- package/hooks/lib/otlp-exporter.js +1 -1
- package/hooks/lib/propose-step.js +1 -1
- package/hooks/lib/provenance-tracker.js +191 -191
- package/hooks/lib/raiz-proyecto.js +158 -102
- package/hooks/lib/resource-quota.js +122 -122
- package/hooks/lib/retry-jitter.js +165 -165
- package/hooks/lib/run-log.js +1 -1
- package/hooks/lib/security-net.js +201 -201
- package/hooks/lib/singleton-guard.js +20 -13
- 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/telegram-cliente.js +11 -3
- package/hooks/lib/text-similarity.js +241 -241
- package/hooks/lib/toon-compressor.js +245 -245
- package/hooks/notificacion-telegram.js +17 -13
- package/hooks/preservar-estado-pre-compact.js +1 -1
- package/hooks/registro-turnos.js +1 -1
- package/hooks/resumen-sesion.js +1 -1
- package/hooks/risk-scoring.js +1 -1
- package/hooks/session-briefing.js +13 -5
- package/hooks/spec-gate.js +1 -1
- package/hooks/sugerir-regenerar-inventario.js +1 -1
- package/hooks/tdd-gate.js +1 -1
- package/hooks/telemetria-agentes.js +1 -1
- package/hooks/telemetria-skill-routing.js +1 -1
- package/hooks/tracking-costos.js +1 -1
- package/hooks/validar-formato-post-subagente.js +1 -1
- package/hooks/validar-intent-spec.js +1 -1
- package/hooks/validar-planning-paths.js +1 -1
- package/instintos/autonomia.yaml +27 -27
- package/instintos/prompt-appendices.yaml +57 -57
- package/llms.txt +29 -29
- package/manifiestos/agent-output-schemas.json +57 -57
- package/manifiestos/canonical-hashes.json +6250 -5257
- package/manifiestos/harness-ir.json +47536 -0
- package/manifiestos/modulos.json +1429 -1428
- package/manifiestos/policy-bundle.json +2065 -0
- package/manifiestos/policy-corpus-w2.json +3926 -0
- package/manifiestos/runtime-adapters-core3.json +208 -0
- package/manifiestos/runtime-conformance.json +139 -0
- package/manifiestos/skills-lock.json +1275 -1275
- package/package.json +94 -94
- package/plantillas/auditor-veto-template.md +105 -105
- 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 +369 -369
- package/reglas/accesibilidad.md +10 -10
- package/reglas/auditorias-documentales-estructurales.md +7 -7
- package/reglas/cloud-infra.md +8 -8
- package/reglas/consultar-vault-primero.md +195 -195
- package/reglas/git-workflow.md +1 -0
- package/reglas/hooks.md +6 -6
- package/reglas/intent-engineering.md +218 -218
- package/reglas/markitdown.md +8 -8
- package/reglas/monitor-ci.md +12 -0
- package/reglas/patrones.md +6 -6
- package/reglas/testing.md +7 -7
- package/reglas/tests-cleanup.md +224 -224
- package/schemas/agent-message.schema.json +73 -73
- package/schemas/agent-output-implementacion.schema.json +114 -114
- package/schemas/agent-output-planificacion.schema.json +150 -150
- package/schemas/agent-output-review.schema.json +98 -98
- package/schemas/diary-entry.schema.json +112 -112
- package/schemas/gate-state.schema.json +76 -0
- package/schemas/harness-ir.schema.json +369 -0
- package/schemas/hook-profiles.schema.json +54 -54
- package/schemas/hooks-config.schema.json +89 -89
- package/schemas/legacy-gates.schema.json +45 -0
- package/schemas/modulos.schema.json +38 -38
- package/schemas/perfiles.schema.json +36 -36
- package/schemas/plugin.schema.json +77 -77
- package/schemas/policy-bundle.schema.json +140 -0
- package/schemas/policy-enforcement.schema.json +117 -0
- package/schemas/policy-operation.schema.json +261 -0
- package/schemas/runtime-adapter.schema.json +176 -0
- package/schemas/runtime-build-attestation.schema.json +100 -0
- package/schemas/runtime-conformance.schema.json +239 -0
- package/schemas/runtime-diagnostic.schema.json +395 -0
- package/schemas/skill-evals.schema.json +119 -119
- package/schemas/skill-frontmatter.schema.json +245 -245
- package/schemas/w4-certification-request.schema.json +72 -0
- package/schemas/w4-certification-verdict.schema.json +224 -0
- package/schemas/w4-corpus.schema.json +172 -0
- package/schemas/w4-mutation-report.schema.json +116 -0
- package/schemas/w4-replay-result.schema.json +164 -0
- package/schemas/w4-scoring-report.schema.json +89 -0
- package/scripts/audit-tools/audit-history.js +330 -330
- package/scripts/audit-tools/bundle-tracker.js +290 -290
- package/scripts/audit-tools/canary-monitor.js +352 -352
- package/scripts/audit-tools/code-profiler.js +605 -605
- package/scripts/audit-tools/dep-doctor.js +320 -320
- package/scripts/audit-tools/env-validator.js +206 -206
- package/scripts/audit-tools/lib/fs-walk.js +48 -48
- package/scripts/audit-tools/lib/output.js +23 -23
- package/scripts/audit-tools/migration-checker.js +392 -392
- package/scripts/audit-tools/pentest-scanner.js +1436 -1436
- package/scripts/auditar-clases-conocidas.js +134 -134
- package/scripts/bootstrap-instintos.js +88 -14
- package/scripts/canario-hooks.js +166 -166
- package/scripts/cli/aprobar-plan.js +73 -73
- package/scripts/cli/autonomia.js +23 -23
- package/scripts/cli/benchmark-memoria.js +37 -37
- package/scripts/cli/briefing.js +23 -23
- package/scripts/cli/ciclo-autonomo.js +73 -73
- package/scripts/cli/ciclo-evolucion.js +26 -26
- package/scripts/cli/ciclo-fase-b.js +102 -102
- package/scripts/cli/derivar-feature-list.js +25 -25
- package/scripts/cli/detectar-host.js +27 -27
- package/scripts/cli/diary-entry.js +69 -69
- package/scripts/cli/execution-state.js +18 -18
- package/scripts/cli/gateway-notify.js +41 -41
- package/scripts/cli/guardrail-metrics.js +39 -39
- package/scripts/cli/liberar-fase.js +42 -42
- package/scripts/cli/mark-evolved.js +56 -56
- package/scripts/cli/memoria-search.js +69 -69
- package/scripts/cli/metricas-dora.js +26 -26
- package/scripts/cli/near-duplicate.js +55 -55
- package/scripts/cli/notificaciones.js +123 -123
- package/scripts/cli/nudge-accionar.js +39 -39
- package/scripts/cli/propose-step.js +29 -29
- package/scripts/cli/run-eval.js +38 -38
- package/scripts/cli/schedule-parse.js +19 -19
- package/scripts/cli/sugerir-modelo.js +20 -20
- package/scripts/cli/verificar-plan.js +36 -36
- package/scripts/cli/verificar-trazabilidad.js +35 -35
- package/scripts/comandos/install-asistido.js +8 -7
- package/scripts/configurar-branch-protection.js +418 -418
- package/scripts/detectar-aprendizajes-duplicados.js +151 -151
- package/scripts/doctor.js +61 -13
- package/scripts/evidencia-valor.js +101 -101
- package/scripts/field-report.js +16 -16
- package/scripts/generar-checklists-consolidados.js +273 -273
- package/scripts/generar-claims-runtime.js +1342 -0
- package/scripts/generar-harness-ir.js +257 -0
- package/scripts/generar-inventario.js +52 -54
- package/scripts/generar-policy-bundle.js +202 -0
- package/scripts/instalador.js +39 -7
- package/scripts/lib/activar-hooks-proyecto.js +116 -116
- package/scripts/lib/approval-receipts.js +190 -0
- 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/certificacion-loop-state.js +421 -0
- package/scripts/lib/ci-reader.js +193 -193
- package/scripts/lib/ciclo-autonomo/candidatos.js +174 -174
- package/scripts/lib/ciclo-autonomo/config.js +165 -165
- package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -174
- package/scripts/lib/ciclo-autonomo/fallback.js +77 -77
- package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -139
- package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -112
- package/scripts/lib/ciclo-autonomo/index.js +301 -301
- package/scripts/lib/ciclo-autonomo/lock.js +124 -124
- package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -122
- package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -240
- package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -248
- package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -190
- package/scripts/lib/ciclo-autonomo/yaml-instintos.js +591 -535
- package/scripts/lib/clasificar-directorio.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -217
- package/scripts/lib/detectar-host-swl.js +175 -175
- package/scripts/lib/detectar-runtime.js +29 -20
- package/scripts/lib/detectar-stack-detallado.js +307 -307
- package/scripts/lib/detector-autoduplicacion-intra-archivo.js +234 -234
- package/scripts/lib/detector-reglas-duplicadas.js +220 -220
- 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/evidence-verifier.js +192 -0
- package/scripts/lib/evidencia-release.js +322 -322
- package/scripts/lib/evidencia-valor.js +228 -228
- package/scripts/lib/expandir-targets.js +71 -71
- package/scripts/lib/frontmatter-canonico.js +509 -0
- package/scripts/lib/gate-engine.js +871 -0
- package/scripts/lib/gate-hooks-requires.js +249 -249
- package/scripts/lib/gate-licencias.js +212 -212
- package/scripts/lib/git-config-preflight.js +48 -0
- package/scripts/lib/git-metricas.js +257 -257
- package/scripts/lib/harness-ir.js +778 -0
- package/scripts/lib/harness-source-snapshot.js +309 -0
- package/scripts/lib/integrity-ledger.js +1147 -0
- package/scripts/lib/jaccard-similarity.js +98 -98
- package/scripts/lib/legacy-gate-migration.js +324 -0
- package/scripts/lib/limpiar-basura-global.js +204 -0
- package/scripts/lib/longmemeval-runner.js +125 -125
- package/scripts/lib/metricas-dora.js +204 -204
- package/scripts/lib/notificaciones-telegram.js +1 -0
- package/scripts/lib/npm-version.js +1 -0
- package/scripts/lib/paquetes-conocidos.js +50 -50
- package/scripts/lib/plan-lock.js +61 -13
- package/scripts/lib/policy-broker.js +338 -0
- package/scripts/lib/policy-bundle.js +342 -0
- package/scripts/lib/policy-context-provider.js +310 -0
- package/scripts/lib/policy-contract.js +479 -0
- package/scripts/lib/policy-verifier-utils.js +65 -0
- package/scripts/lib/pr-analyzer.js +399 -399
- package/scripts/lib/principal-verifier.js +178 -0
- package/scripts/lib/prompt-builder.js +264 -264
- package/scripts/lib/resolver-plan-fase.js +37 -37
- package/scripts/lib/rrf-fusion.js +175 -175
- package/scripts/lib/runtime-adapter-contract.js +267 -0
- package/scripts/lib/runtime-artifact-verifier.js +426 -0
- package/scripts/lib/runtime-build-attestation.js +127 -0
- package/scripts/lib/runtime-bundle-installer.js +586 -0
- package/scripts/lib/runtime-compiler.js +327 -0
- package/scripts/lib/runtime-conformance.js +202 -0
- package/scripts/lib/runtime-doctor-core3.js +567 -0
- package/scripts/lib/runtime-doctor-input.js +59 -0
- package/scripts/lib/runtime-operation-adapter.js +267 -0
- package/scripts/lib/schema-version.js +164 -164
- package/scripts/lib/semantic-search.js +252 -252
- package/scripts/lib/signed-envelope.js +545 -0
- package/scripts/lib/single-use-store.js +359 -0
- package/scripts/lib/skills-externas.js +31 -0
- package/scripts/lib/toml-merge.js +204 -204
- package/scripts/lib/transformadores/codex.js +15 -8
- package/scripts/lib/transformadores/gemini.js +79 -5
- package/scripts/lib/w4-attestation-adapter.js +158 -0
- package/scripts/lib/w4-canario.js +337 -0
- package/scripts/lib/w4-claims.js +182 -0
- package/scripts/lib/w4-corpus-generador.js +542 -0
- package/scripts/lib/w4-gate-c5.js +115 -0
- package/scripts/lib/w4-harness-bajo-prueba.js +155 -0
- package/scripts/lib/w4-matriz-combos.js +55 -0
- package/scripts/lib/w4-motor-mutacion.js +1348 -0
- package/scripts/lib/w4-motor-replay.js +735 -0
- package/scripts/lib/w4-pin-origen.js +54 -0
- package/scripts/lib/w4-publicar-request.js +132 -0
- package/scripts/lib/w4-revocacion.js +62 -0
- package/scripts/lib/w4-runtimes-core3.js +38 -0
- package/scripts/lib/w4-scorer-certificacion.js +692 -0
- package/scripts/lib/w4-superficie-candidato.js +49 -0
- package/scripts/lib/w4-veredicto.js +452 -0
- package/scripts/lib/w4-verificar-veredicto.js +302 -0
- package/scripts/limpiar-artefactos-python.js +131 -131
- package/scripts/mcp-server/auth.js +105 -105
- package/scripts/mcp-server/cache.js +106 -106
- package/scripts/migrar-csv-a-array.js +168 -168
- package/scripts/migrar-fase-dominio.js +200 -200
- package/scripts/migrar-gates-legacy.js +108 -0
- package/scripts/publicar-certification-request.js +115 -0
- package/scripts/runtime-doctor.js +107 -0
- package/scripts/tui/componentes/selector-multi.js +189 -189
- package/scripts/tui/componentes/selector-unico.js +158 -158
- package/scripts/tui/ejecutores.js +375 -375
- package/scripts/tui/lib/colores.js +129 -129
- package/scripts/tui/lib/render.js +264 -264
- package/scripts/tui/lib/teclas.js +113 -113
- package/scripts/tui/pantallas/install-wizard.js +408 -403
- package/scripts/tui/pantallas/menu-principal.js +52 -52
- package/scripts/tui/pantallas/progreso.js +274 -274
- package/scripts/tui/pantallas/resumen.js +132 -132
- package/scripts/validar-userland-vacio.js +110 -110
- package/scripts/verificar-aislamiento-swl-eval.js +87 -0
- package/scripts/verificar-empaquetado-downstream.js +375 -0
- package/scripts/verificar-loop-constructor.js +215 -0
- package/scripts/verificar-trazabilidad.js +13 -6
- package/scripts/verificar-veredicto-real.js +84 -0
- package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +0 -53
- package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +0 -372
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Auth opt-in para swl-mcp-server v1.0.0 (ADR-0019 Sub-fase 3).
|
|
5
|
-
*
|
|
6
|
-
* El stub experimental v0.1.x corría sin auth. Cualquier proceso con acceso al
|
|
7
|
-
* stdio podía leer toda la memoria SWL. Esa decisión era aceptable solo en
|
|
8
|
-
* single-user local — no en multi-usuario, no expuesto a red, no compartido.
|
|
9
|
-
*
|
|
10
|
-
* v1.0.0 introduce auth **opt-in**:
|
|
11
|
-
* - Si `SWL_MCP_API_KEY` NO está definida en el entorno del server, el comportamiento
|
|
12
|
-
* es idéntico al stub (sin auth). Compatibilidad total con clientes existentes.
|
|
13
|
-
* - Si `SWL_MCP_API_KEY` ESTÁ definida, cada `tools/call` debe incluir
|
|
14
|
-
* `params._auth = "<api-key>"`. Sin el token o con token incorrecto, se devuelve
|
|
15
|
-
* `-32001 Unauthorized`.
|
|
16
|
-
*
|
|
17
|
-
* Decisión deliberada de NO usar header `Authorization: Bearer ...`:
|
|
18
|
-
* - El protocolo MCP sobre stdio NO transporta headers HTTP.
|
|
19
|
-
* - Inventar un campo en `initialize.capabilities` específico para swl-ses
|
|
20
|
-
* rompería la spec del protocolo.
|
|
21
|
-
* - `_auth` como campo en `params` es el patrón de menor fricción.
|
|
22
|
-
*
|
|
23
|
-
* Limitaciones aceptadas:
|
|
24
|
-
* - Token estático sin rotación automática — el operador rota manualmente
|
|
25
|
-
* cambiando la env var del proceso.
|
|
26
|
-
* - Sin scopes (read/write) porque v1 sigue siendo read-only.
|
|
27
|
-
*
|
|
28
|
-
* @module scripts/mcp-server/auth
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
const ENV_VAR_NAME = 'SWL_MCP_API_KEY';
|
|
32
|
-
const ERROR_CODE_UNAUTHORIZED = -32001;
|
|
33
|
-
const ERROR_CODE_FORBIDDEN = -32002;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Construye un validador de auth desde el entorno actual.
|
|
37
|
-
*
|
|
38
|
-
* Pattern de "construct once, use many": leer la env var una sola vez al arranque
|
|
39
|
-
* y devolver una función pura que valida cada request. Evita race conditions con
|
|
40
|
-
* tests que mutan process.env.
|
|
41
|
-
*
|
|
42
|
-
* @param {object} [opciones] - { env: NodeJS.ProcessEnv } sustituible para tests.
|
|
43
|
-
* @returns {{ requerida: boolean, validar: (request: object) => { ok: boolean, code?: number, message?: string } }}
|
|
44
|
-
*/
|
|
45
|
-
function construirValidador(opciones = {}) {
|
|
46
|
-
const env = opciones.env || process.env;
|
|
47
|
-
const apiKey = env[ENV_VAR_NAME];
|
|
48
|
-
const requerida = typeof apiKey === 'string' && apiKey.length > 0;
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
requerida,
|
|
52
|
-
validar: (request) => {
|
|
53
|
-
if (!requerida) return { ok: true };
|
|
54
|
-
// Solo validar tools/call — initialize, ping, tools/list son metadata pública.
|
|
55
|
-
const metodo = request && request.method;
|
|
56
|
-
if (metodo !== 'tools/call') return { ok: true };
|
|
57
|
-
|
|
58
|
-
const params = request.params || {};
|
|
59
|
-
const tokenCliente = params._auth;
|
|
60
|
-
|
|
61
|
-
if (typeof tokenCliente !== 'string' || tokenCliente.length === 0) {
|
|
62
|
-
return {
|
|
63
|
-
ok: false,
|
|
64
|
-
code: ERROR_CODE_UNAUTHORIZED,
|
|
65
|
-
message: 'swl-mcp-server requiere autenticación: SWL_MCP_API_KEY está configurada en el server. El cliente debe enviar params._auth con el API key.',
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
if (!comparacionConstante(tokenCliente, apiKey)) {
|
|
69
|
-
return {
|
|
70
|
-
ok: false,
|
|
71
|
-
code: ERROR_CODE_FORBIDDEN,
|
|
72
|
-
message: 'Token inválido.',
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return { ok: true };
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Comparación de strings en tiempo constante para evitar timing attacks
|
|
82
|
-
* sobre el API key. Implementación zero-deps simple.
|
|
83
|
-
*
|
|
84
|
-
* Si las longitudes difieren, igual se itera la longitud máxima para no filtrar
|
|
85
|
-
* información sobre el largo del secreto vía duración de la comparación.
|
|
86
|
-
*/
|
|
87
|
-
function comparacionConstante(a, b) {
|
|
88
|
-
if (typeof a !== 'string' || typeof b !== 'string') return false;
|
|
89
|
-
const len = Math.max(a.length, b.length);
|
|
90
|
-
let diff = a.length ^ b.length;
|
|
91
|
-
for (let i = 0; i < len; i++) {
|
|
92
|
-
const ca = i < a.length ? a.charCodeAt(i) : 0;
|
|
93
|
-
const cb = i < b.length ? b.charCodeAt(i) : 0;
|
|
94
|
-
diff |= ca ^ cb;
|
|
95
|
-
}
|
|
96
|
-
return diff === 0;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
module.exports = {
|
|
100
|
-
construirValidador,
|
|
101
|
-
comparacionConstante,
|
|
102
|
-
ENV_VAR_NAME,
|
|
103
|
-
ERROR_CODE_UNAUTHORIZED,
|
|
104
|
-
ERROR_CODE_FORBIDDEN,
|
|
105
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth opt-in para swl-mcp-server v1.0.0 (ADR-0019 Sub-fase 3).
|
|
5
|
+
*
|
|
6
|
+
* El stub experimental v0.1.x corría sin auth. Cualquier proceso con acceso al
|
|
7
|
+
* stdio podía leer toda la memoria SWL. Esa decisión era aceptable solo en
|
|
8
|
+
* single-user local — no en multi-usuario, no expuesto a red, no compartido.
|
|
9
|
+
*
|
|
10
|
+
* v1.0.0 introduce auth **opt-in**:
|
|
11
|
+
* - Si `SWL_MCP_API_KEY` NO está definida en el entorno del server, el comportamiento
|
|
12
|
+
* es idéntico al stub (sin auth). Compatibilidad total con clientes existentes.
|
|
13
|
+
* - Si `SWL_MCP_API_KEY` ESTÁ definida, cada `tools/call` debe incluir
|
|
14
|
+
* `params._auth = "<api-key>"`. Sin el token o con token incorrecto, se devuelve
|
|
15
|
+
* `-32001 Unauthorized`.
|
|
16
|
+
*
|
|
17
|
+
* Decisión deliberada de NO usar header `Authorization: Bearer ...`:
|
|
18
|
+
* - El protocolo MCP sobre stdio NO transporta headers HTTP.
|
|
19
|
+
* - Inventar un campo en `initialize.capabilities` específico para swl-ses
|
|
20
|
+
* rompería la spec del protocolo.
|
|
21
|
+
* - `_auth` como campo en `params` es el patrón de menor fricción.
|
|
22
|
+
*
|
|
23
|
+
* Limitaciones aceptadas:
|
|
24
|
+
* - Token estático sin rotación automática — el operador rota manualmente
|
|
25
|
+
* cambiando la env var del proceso.
|
|
26
|
+
* - Sin scopes (read/write) porque v1 sigue siendo read-only.
|
|
27
|
+
*
|
|
28
|
+
* @module scripts/mcp-server/auth
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const ENV_VAR_NAME = 'SWL_MCP_API_KEY';
|
|
32
|
+
const ERROR_CODE_UNAUTHORIZED = -32001;
|
|
33
|
+
const ERROR_CODE_FORBIDDEN = -32002;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Construye un validador de auth desde el entorno actual.
|
|
37
|
+
*
|
|
38
|
+
* Pattern de "construct once, use many": leer la env var una sola vez al arranque
|
|
39
|
+
* y devolver una función pura que valida cada request. Evita race conditions con
|
|
40
|
+
* tests que mutan process.env.
|
|
41
|
+
*
|
|
42
|
+
* @param {object} [opciones] - { env: NodeJS.ProcessEnv } sustituible para tests.
|
|
43
|
+
* @returns {{ requerida: boolean, validar: (request: object) => { ok: boolean, code?: number, message?: string } }}
|
|
44
|
+
*/
|
|
45
|
+
function construirValidador(opciones = {}) {
|
|
46
|
+
const env = opciones.env || process.env;
|
|
47
|
+
const apiKey = env[ENV_VAR_NAME];
|
|
48
|
+
const requerida = typeof apiKey === 'string' && apiKey.length > 0;
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
requerida,
|
|
52
|
+
validar: (request) => {
|
|
53
|
+
if (!requerida) return { ok: true };
|
|
54
|
+
// Solo validar tools/call — initialize, ping, tools/list son metadata pública.
|
|
55
|
+
const metodo = request && request.method;
|
|
56
|
+
if (metodo !== 'tools/call') return { ok: true };
|
|
57
|
+
|
|
58
|
+
const params = request.params || {};
|
|
59
|
+
const tokenCliente = params._auth;
|
|
60
|
+
|
|
61
|
+
if (typeof tokenCliente !== 'string' || tokenCliente.length === 0) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
code: ERROR_CODE_UNAUTHORIZED,
|
|
65
|
+
message: 'swl-mcp-server requiere autenticación: SWL_MCP_API_KEY está configurada en el server. El cliente debe enviar params._auth con el API key.',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (!comparacionConstante(tokenCliente, apiKey)) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
code: ERROR_CODE_FORBIDDEN,
|
|
72
|
+
message: 'Token inválido.',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { ok: true };
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Comparación de strings en tiempo constante para evitar timing attacks
|
|
82
|
+
* sobre el API key. Implementación zero-deps simple.
|
|
83
|
+
*
|
|
84
|
+
* Si las longitudes difieren, igual se itera la longitud máxima para no filtrar
|
|
85
|
+
* información sobre el largo del secreto vía duración de la comparación.
|
|
86
|
+
*/
|
|
87
|
+
function comparacionConstante(a, b) {
|
|
88
|
+
if (typeof a !== 'string' || typeof b !== 'string') return false;
|
|
89
|
+
const len = Math.max(a.length, b.length);
|
|
90
|
+
let diff = a.length ^ b.length;
|
|
91
|
+
for (let i = 0; i < len; i++) {
|
|
92
|
+
const ca = i < a.length ? a.charCodeAt(i) : 0;
|
|
93
|
+
const cb = i < b.length ? b.charCodeAt(i) : 0;
|
|
94
|
+
diff |= ca ^ cb;
|
|
95
|
+
}
|
|
96
|
+
return diff === 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
construirValidador,
|
|
101
|
+
comparacionConstante,
|
|
102
|
+
ENV_VAR_NAME,
|
|
103
|
+
ERROR_CODE_UNAUTHORIZED,
|
|
104
|
+
ERROR_CODE_FORBIDDEN,
|
|
105
|
+
};
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Cache mtime-based para handlers del swl-mcp-server v1.0.0 (ADR-0019 Sub-fase 3).
|
|
5
|
-
*
|
|
6
|
-
* El stub experimental leía disco en cada call (latencia medida ~10ms con
|
|
7
|
-
* APRENDIZAJES.md de 1172 líneas). Para datasets más grandes (>10k líneas) o
|
|
8
|
-
* múltiples clientes concurrentes, el caching reduce sustancialmente la carga.
|
|
9
|
-
*
|
|
10
|
-
* Patrón:
|
|
11
|
-
* - Key = path absoluto del archivo.
|
|
12
|
-
* - Value = { mtime, contenido, parsed }.
|
|
13
|
-
* - Invalidación: si fs.stat().mtime > value.mtime → recargar y reparsear.
|
|
14
|
-
* - TTL opcional vía `SWL_MCP_CACHE_TTL_MS` (default 60000 ms): aunque mtime no
|
|
15
|
-
* haya cambiado, recargar tras TTL para defensa contra clock skew o ediciones
|
|
16
|
-
* que no actualizan mtime (raras pero posibles en filesystems exóticos).
|
|
17
|
-
*
|
|
18
|
-
* Zero-deps. NO usar para escritura — sigue read-only.
|
|
19
|
-
*
|
|
20
|
-
* @module scripts/mcp-server/cache
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
const fs = require('fs');
|
|
24
|
-
|
|
25
|
-
const DEFAULT_TTL_MS = 60 * 1000;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Crea una instancia de cache mtime-based.
|
|
29
|
-
*
|
|
30
|
-
* @param {object} [opciones]
|
|
31
|
-
* @param {number} [opciones.ttlMs] - TTL en milisegundos. Default 60000.
|
|
32
|
-
* @param {object} [opciones.env] - Para leer SWL_MCP_CACHE_TTL_MS en tests.
|
|
33
|
-
* @returns {{ get: Function, invalidate: Function, stats: Function, _store: Map }}
|
|
34
|
-
*/
|
|
35
|
-
function crearCache(opciones = {}) {
|
|
36
|
-
const env = opciones.env || process.env;
|
|
37
|
-
const ttlMs = opciones.ttlMs !== undefined
|
|
38
|
-
? opciones.ttlMs
|
|
39
|
-
: (parseInt(env.SWL_MCP_CACHE_TTL_MS, 10) || DEFAULT_TTL_MS);
|
|
40
|
-
|
|
41
|
-
const store = new Map();
|
|
42
|
-
const stats = { hits: 0, misses: 0, invalidations: 0 };
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Obtiene el valor cacheado para `path`. Si el archivo cambió (mtime) o el TTL
|
|
46
|
-
* expiró, vuelve a leer y parsear con `parser(contenido, path)`.
|
|
47
|
-
*
|
|
48
|
-
* @param {string} ruta - Path absoluto del archivo a cachear.
|
|
49
|
-
* @param {(contenido: string, ruta: string) => any} parser - Función que transforma
|
|
50
|
-
* el contenido del archivo en el objeto a cachear. DEBE ser pura.
|
|
51
|
-
* @returns {{ data: any, hit: boolean } | null} null si el archivo no existe.
|
|
52
|
-
*/
|
|
53
|
-
function get(ruta, parser) {
|
|
54
|
-
let stat;
|
|
55
|
-
try {
|
|
56
|
-
stat = fs.statSync(ruta);
|
|
57
|
-
} catch (err) {
|
|
58
|
-
if (err.code === 'ENOENT') return null;
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const mtimeMs = stat.mtimeMs;
|
|
63
|
-
const ahora = Date.now();
|
|
64
|
-
const cached = store.get(ruta);
|
|
65
|
-
|
|
66
|
-
if (cached && cached.mtimeMs === mtimeMs && (ahora - cached.cargadoEn) < ttlMs) {
|
|
67
|
-
stats.hits++;
|
|
68
|
-
return { data: cached.data, hit: true };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (cached) stats.invalidations++;
|
|
72
|
-
else stats.misses++;
|
|
73
|
-
|
|
74
|
-
const contenido = fs.readFileSync(ruta, 'utf-8');
|
|
75
|
-
const data = parser(contenido, ruta);
|
|
76
|
-
store.set(ruta, { mtimeMs, cargadoEn: ahora, data });
|
|
77
|
-
return { data, hit: false };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Invalida una entrada o todo el cache.
|
|
82
|
-
* @param {string} [ruta] - Si se omite, vacía todo.
|
|
83
|
-
*/
|
|
84
|
-
function invalidate(ruta) {
|
|
85
|
-
if (ruta === undefined) {
|
|
86
|
-
const n = store.size;
|
|
87
|
-
store.clear();
|
|
88
|
-
stats.invalidations += n;
|
|
89
|
-
return n;
|
|
90
|
-
}
|
|
91
|
-
if (store.delete(ruta)) stats.invalidations++;
|
|
92
|
-
return 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
get,
|
|
97
|
-
invalidate,
|
|
98
|
-
stats: () => ({ ...stats, size: store.size, ttlMs }),
|
|
99
|
-
_store: store, // exposed para tests
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
module.exports = {
|
|
104
|
-
crearCache,
|
|
105
|
-
DEFAULT_TTL_MS,
|
|
106
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cache mtime-based para handlers del swl-mcp-server v1.0.0 (ADR-0019 Sub-fase 3).
|
|
5
|
+
*
|
|
6
|
+
* El stub experimental leía disco en cada call (latencia medida ~10ms con
|
|
7
|
+
* APRENDIZAJES.md de 1172 líneas). Para datasets más grandes (>10k líneas) o
|
|
8
|
+
* múltiples clientes concurrentes, el caching reduce sustancialmente la carga.
|
|
9
|
+
*
|
|
10
|
+
* Patrón:
|
|
11
|
+
* - Key = path absoluto del archivo.
|
|
12
|
+
* - Value = { mtime, contenido, parsed }.
|
|
13
|
+
* - Invalidación: si fs.stat().mtime > value.mtime → recargar y reparsear.
|
|
14
|
+
* - TTL opcional vía `SWL_MCP_CACHE_TTL_MS` (default 60000 ms): aunque mtime no
|
|
15
|
+
* haya cambiado, recargar tras TTL para defensa contra clock skew o ediciones
|
|
16
|
+
* que no actualizan mtime (raras pero posibles en filesystems exóticos).
|
|
17
|
+
*
|
|
18
|
+
* Zero-deps. NO usar para escritura — sigue read-only.
|
|
19
|
+
*
|
|
20
|
+
* @module scripts/mcp-server/cache
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
|
|
25
|
+
const DEFAULT_TTL_MS = 60 * 1000;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Crea una instancia de cache mtime-based.
|
|
29
|
+
*
|
|
30
|
+
* @param {object} [opciones]
|
|
31
|
+
* @param {number} [opciones.ttlMs] - TTL en milisegundos. Default 60000.
|
|
32
|
+
* @param {object} [opciones.env] - Para leer SWL_MCP_CACHE_TTL_MS en tests.
|
|
33
|
+
* @returns {{ get: Function, invalidate: Function, stats: Function, _store: Map }}
|
|
34
|
+
*/
|
|
35
|
+
function crearCache(opciones = {}) {
|
|
36
|
+
const env = opciones.env || process.env;
|
|
37
|
+
const ttlMs = opciones.ttlMs !== undefined
|
|
38
|
+
? opciones.ttlMs
|
|
39
|
+
: (parseInt(env.SWL_MCP_CACHE_TTL_MS, 10) || DEFAULT_TTL_MS);
|
|
40
|
+
|
|
41
|
+
const store = new Map();
|
|
42
|
+
const stats = { hits: 0, misses: 0, invalidations: 0 };
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Obtiene el valor cacheado para `path`. Si el archivo cambió (mtime) o el TTL
|
|
46
|
+
* expiró, vuelve a leer y parsear con `parser(contenido, path)`.
|
|
47
|
+
*
|
|
48
|
+
* @param {string} ruta - Path absoluto del archivo a cachear.
|
|
49
|
+
* @param {(contenido: string, ruta: string) => any} parser - Función que transforma
|
|
50
|
+
* el contenido del archivo en el objeto a cachear. DEBE ser pura.
|
|
51
|
+
* @returns {{ data: any, hit: boolean } | null} null si el archivo no existe.
|
|
52
|
+
*/
|
|
53
|
+
function get(ruta, parser) {
|
|
54
|
+
let stat;
|
|
55
|
+
try {
|
|
56
|
+
stat = fs.statSync(ruta);
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (err.code === 'ENOENT') return null;
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const mtimeMs = stat.mtimeMs;
|
|
63
|
+
const ahora = Date.now();
|
|
64
|
+
const cached = store.get(ruta);
|
|
65
|
+
|
|
66
|
+
if (cached && cached.mtimeMs === mtimeMs && (ahora - cached.cargadoEn) < ttlMs) {
|
|
67
|
+
stats.hits++;
|
|
68
|
+
return { data: cached.data, hit: true };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (cached) stats.invalidations++;
|
|
72
|
+
else stats.misses++;
|
|
73
|
+
|
|
74
|
+
const contenido = fs.readFileSync(ruta, 'utf-8');
|
|
75
|
+
const data = parser(contenido, ruta);
|
|
76
|
+
store.set(ruta, { mtimeMs, cargadoEn: ahora, data });
|
|
77
|
+
return { data, hit: false };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Invalida una entrada o todo el cache.
|
|
82
|
+
* @param {string} [ruta] - Si se omite, vacía todo.
|
|
83
|
+
*/
|
|
84
|
+
function invalidate(ruta) {
|
|
85
|
+
if (ruta === undefined) {
|
|
86
|
+
const n = store.size;
|
|
87
|
+
store.clear();
|
|
88
|
+
stats.invalidations += n;
|
|
89
|
+
return n;
|
|
90
|
+
}
|
|
91
|
+
if (store.delete(ruta)) stats.invalidations++;
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
get,
|
|
97
|
+
invalidate,
|
|
98
|
+
stats: () => ({ ...stats, size: store.size, ttlMs }),
|
|
99
|
+
_store: store, // exposed para tests
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
module.exports = {
|
|
104
|
+
crearCache,
|
|
105
|
+
DEFAULT_TTL_MS,
|
|
106
|
+
};
|