@saulwade/swl-ses 1.0.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 +238 -0
- package/README.md +560 -0
- package/_userland/agentes/.gitkeep +0 -0
- package/_userland/habilidades/.gitkeep +0 -0
- package/agentes/.evolved.json +9 -0
- package/agentes/accesibilidad-wcag-swl.md +692 -0
- package/agentes/arquitecto-swl.md +238 -0
- package/agentes/auto-evolucion-swl.md +854 -0
- package/agentes/backend-api-swl.md +470 -0
- package/agentes/backend-csharp-swl.md +418 -0
- package/agentes/backend-go-swl.md +388 -0
- package/agentes/backend-java-swl.md +279 -0
- package/agentes/backend-node-swl.md +477 -0
- package/agentes/backend-python-swl.md +608 -0
- package/agentes/backend-rust-swl.md +362 -0
- package/agentes/backend-workers-swl.md +480 -0
- package/agentes/cloud-infra-swl.md +485 -0
- package/agentes/consolidador-swl.md +539 -0
- package/agentes/datos-swl.md +584 -0
- package/agentes/depurador-swl.md +349 -0
- package/agentes/devops-ci-swl.md +374 -0
- package/agentes/disenador-ui-swl.md +558 -0
- package/agentes/documentador-swl.md +343 -0
- package/agentes/evals/arquitecto-swl.evals.json +56 -0
- package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
- package/agentes/evals/implementador-swl.evals.json +56 -0
- package/agentes/evals/orquestador-swl.evals.json +60 -0
- package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
- package/agentes/evals/red-team-swl.evals.json +59 -0
- package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
- package/agentes/frontend-angular-swl.md +627 -0
- package/agentes/frontend-css-swl.md +720 -0
- package/agentes/frontend-react-swl.md +696 -0
- package/agentes/frontend-swl.md +500 -0
- package/agentes/frontend-tailwind-swl.md +830 -0
- package/agentes/implementador-swl.md +328 -0
- package/agentes/investigador-swl.md +430 -0
- package/agentes/investigador-ux-swl.md +500 -0
- package/agentes/llm-apps-swl.md +276 -0
- package/agentes/migrador-swl.md +417 -0
- package/agentes/mobile-android-swl.md +509 -0
- package/agentes/mobile-cross-swl.md +539 -0
- package/agentes/mobile-ios-swl.md +500 -0
- package/agentes/mobile-testing-swl.md +300 -0
- package/agentes/notificador-swl.md +916 -0
- package/agentes/observabilidad-swl.md +436 -0
- package/agentes/orquestador-swl.md +884 -0
- package/agentes/pagos-swl.md +283 -0
- package/agentes/perfilador-usuario-swl.md +306 -0
- package/agentes/planificador-swl.md +402 -0
- package/agentes/producto-prd-swl.md +587 -0
- package/agentes/red-team-swl.md +216 -0
- package/agentes/release-manager-swl.md +568 -0
- package/agentes/rendimiento-swl.md +714 -0
- package/agentes/resolutor-build-swl.md +243 -0
- package/agentes/revisor-angular-swl.md +276 -0
- package/agentes/revisor-codigo-swl.md +348 -0
- package/agentes/revisor-csharp-swl.md +262 -0
- package/agentes/revisor-go-swl.md +257 -0
- package/agentes/revisor-java-swl.md +255 -0
- package/agentes/revisor-kotlin-swl.md +271 -0
- package/agentes/revisor-nextjs-swl.md +279 -0
- package/agentes/revisor-php-swl.md +269 -0
- package/agentes/revisor-react-swl.md +276 -0
- package/agentes/revisor-rust-swl.md +344 -0
- package/agentes/revisor-seguridad-swl.md +390 -0
- package/agentes/revisor-swift-swl.md +266 -0
- package/agentes/revisor-typescript-swl.md +344 -0
- package/agentes/sre-swl.md +265 -0
- package/agentes/tdd-qa-swl.md +354 -0
- package/agentes/ux-disenador-swl.md +501 -0
- package/bin/lib/bot-comandos.js +1030 -0
- package/bin/lib/bot-discovery.js +182 -0
- package/bin/lib/bot-git.js +142 -0
- package/bin/swl-ses.js +325 -0
- package/bin/swl-telegram-bot.js +442 -0
- package/bin/swl-telegram-bot.plist +21 -0
- package/bin/swl-telegram-bot.service +14 -0
- package/comandos/swl/.evolved.json +23 -0
- package/comandos/swl/actualizar.md +174 -0
- package/comandos/swl/adoptar-proyecto.md +207 -0
- package/comandos/swl/aprender.md +701 -0
- package/comandos/swl/auditar-deps.md +134 -0
- package/comandos/swl/autoresearch.md +170 -0
- package/comandos/swl/ayuda.md +224 -0
- package/comandos/swl/brainstorm.md +50 -0
- package/comandos/swl/checkpoint.md +330 -0
- package/comandos/swl/compactar.md +283 -0
- package/comandos/swl/configurar-ci.md +227 -0
- package/comandos/swl/contexto.md +112 -0
- package/comandos/swl/contribuir.md +233 -0
- package/comandos/swl/crear-skill.md +292 -0
- package/comandos/swl/cron.md +196 -0
- package/comandos/swl/dashboard.md +146 -0
- package/comandos/swl/discutir-fase.md +230 -0
- package/comandos/swl/ejecutar-fase.md +135 -0
- package/comandos/swl/evaluar-skill.md +487 -0
- package/comandos/swl/evolucion-estado.md +142 -0
- package/comandos/swl/evolucionar.md +259 -0
- package/comandos/swl/exportar-vault.md +189 -0
- package/comandos/swl/gateway.md +158 -0
- package/comandos/swl/inbox.md +116 -0
- package/comandos/swl/instalar.md +220 -0
- package/comandos/swl/instintos.md +86 -0
- package/comandos/swl/mapear-codebase.md +312 -0
- package/comandos/swl/mcp-status.md +175 -0
- package/comandos/swl/metricas.md +270 -0
- package/comandos/swl/modelo.md +102 -0
- package/comandos/swl/notificaciones.md +396 -0
- package/comandos/swl/nuevo-proyecto.md +154 -0
- package/comandos/swl/planear-fase.md +221 -0
- package/comandos/swl/plugins.md +256 -0
- package/comandos/swl/reflect-skills.md +125 -0
- package/comandos/swl/release.md +217 -0
- package/comandos/swl/revisar-impacto.md +206 -0
- package/comandos/swl/revisar.md +330 -0
- package/comandos/swl/salud.md +363 -0
- package/comandos/swl/sesiones.md +200 -0
- package/comandos/swl/skill-search.md +113 -0
- package/comandos/swl/verificar.md +585 -0
- package/comandos/swl/wiki.md +620 -0
- package/contextos/dev.md +32 -0
- package/contextos/research.md +30 -0
- package/contextos/review.md +31 -0
- package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
- package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
- package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
- package/habilidades/agent-browser/SKILL.md +218 -0
- package/habilidades/agentes-como-servicio/SKILL.md +218 -0
- package/habilidades/ai-runtime-security/SKILL.md +273 -0
- package/habilidades/angular-avanzado/SKILL.md +164 -0
- package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
- package/habilidades/angular-moderno/SKILL.md +186 -0
- package/habilidades/angular-moderno/evals/evals.json +45 -0
- package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
- package/habilidades/api-rest-diseno/SKILL.md +191 -0
- package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
- package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
- package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
- package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
- package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
- package/habilidades/async-python/SKILL.md +149 -0
- package/habilidades/async-python/evals/evals.json +47 -0
- package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
- package/habilidades/auth-patrones/.evolved.json +9 -0
- package/habilidades/auth-patrones/SKILL.md +413 -0
- package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
- package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
- package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
- package/habilidades/autoresearch/SKILL.md +268 -0
- package/habilidades/autoresearch/evals/evals.json +41 -0
- package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
- package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
- package/habilidades/azure-cloud/SKILL.md +308 -0
- package/habilidades/azure-cloud/recursos/aks.md +327 -0
- package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
- package/habilidades/backend-production-resilience/SKILL.md +288 -0
- package/habilidades/brainstorming/SKILL.md +295 -0
- package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
- package/habilidades/build-errors-cpp/SKILL.md +270 -0
- package/habilidades/build-errors-csharp/SKILL.md +265 -0
- package/habilidades/build-errors-go/SKILL.md +306 -0
- package/habilidades/build-errors-java/SKILL.md +278 -0
- package/habilidades/build-errors-kotlin/SKILL.md +303 -0
- package/habilidades/build-errors-nextjs/SKILL.md +312 -0
- package/habilidades/build-errors-php/SKILL.md +270 -0
- package/habilidades/build-errors-python/SKILL.md +292 -0
- package/habilidades/build-errors-rust/SKILL.md +284 -0
- package/habilidades/build-errors-swift/SKILL.md +272 -0
- package/habilidades/build-errors-typescript/SKILL.md +369 -0
- package/habilidades/checklist-calidad/SKILL.md +271 -0
- package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
- package/habilidades/checklist-seguridad/SKILL.md +285 -0
- package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
- package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
- package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
- package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
- package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
- package/habilidades/cloud-aws/SKILL.md +142 -0
- package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
- package/habilidades/compactacion-contexto/SKILL.md +247 -0
- package/habilidades/contenedores-docker/SKILL.md +137 -0
- package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
- package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
- package/habilidades/context-builder/SKILL.md +170 -0
- package/habilidades/control-profundidad/SKILL.md +128 -0
- package/habilidades/csharp-experto/SKILL.md +322 -0
- package/habilidades/csharp-patrones/SKILL.md +316 -0
- package/habilidades/csharp-testing/SKILL.md +286 -0
- package/habilidades/css-moderno/SKILL.md +166 -0
- package/habilidades/css-moderno/evals/evals.json +43 -0
- package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
- package/habilidades/datos-etl/SKILL.md +129 -0
- package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
- package/habilidades/dbml-experto/SKILL.md +339 -0
- package/habilidades/dbml-experto/evals/evals.json +56 -0
- package/habilidades/dependencias-auditoria/SKILL.md +320 -0
- package/habilidades/deprecacion-migracion/SKILL.md +169 -0
- package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
- package/habilidades/design-tokens/SKILL.md +158 -0
- package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
- package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
- package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
- package/habilidades/discutir-fase/SKILL.md +188 -0
- package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
- package/habilidades/diseno-responsivo/SKILL.md +186 -0
- package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
- package/habilidades/django-experto/SKILL.md +205 -0
- package/habilidades/django-experto/recursos/async-django.md +390 -0
- package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
- package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
- package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
- package/habilidades/django-experto/recursos/testing-django.md +415 -0
- package/habilidades/doc-sync/SKILL.md +280 -0
- package/habilidades/drift-detection/SKILL.md +179 -0
- package/habilidades/ejecutar-fase/SKILL.md +468 -0
- package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
- package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
- package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
- package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
- package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
- package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -0
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
- package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
- package/habilidades/evaluacion-agentes/SKILL.md +314 -0
- package/habilidades/event-driven/SKILL.md +153 -0
- package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
- package/habilidades/extraccion-documentos/SKILL.md +221 -0
- package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
- package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
- package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
- package/habilidades/fastapi-experto/SKILL.md +221 -0
- package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
- package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
- package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
- package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
- package/habilidades/filament-admin/SKILL.md +290 -0
- package/habilidades/frontend-avanzado/SKILL.md +257 -0
- package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
- package/habilidades/gcp-cloud/SKILL.md +260 -0
- package/habilidades/gcp-cloud/recursos/gke.md +234 -0
- package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
- package/habilidades/generacion-mermaid/SKILL.md +229 -0
- package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
- package/habilidades/go-experto/SKILL.md +305 -0
- package/habilidades/go-patrones/SKILL.md +299 -0
- package/habilidades/go-testing/SKILL.md +291 -0
- package/habilidades/graphql-experto/SKILL.md +323 -0
- package/habilidades/guardrail-semantico/SKILL.md +282 -0
- package/habilidades/harness-claude-code/SKILL.md +299 -0
- package/habilidades/iam-secretos/SKILL.md +265 -0
- package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
- package/habilidades/infra-github-actions/SKILL.md +166 -0
- package/habilidades/instalar-sistema/.evolved.json +9 -0
- package/habilidades/instalar-sistema/SKILL.md +221 -0
- package/habilidades/java-experto/SKILL.md +290 -0
- package/habilidades/java-patrones/SKILL.md +275 -0
- package/habilidades/java-testing/SKILL.md +288 -0
- package/habilidades/kotlin-compose/SKILL.md +278 -0
- package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
- package/habilidades/kotlin-experto/SKILL.md +318 -0
- package/habilidades/kotlin-testing/SKILL.md +267 -0
- package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
- package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
- package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
- package/habilidades/langchain-langraph/SKILL.md +386 -0
- package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
- package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
- package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
- package/habilidades/legacy-code-rescue/SKILL.md +267 -0
- package/habilidades/likec4-experto/SKILL.md +412 -0
- package/habilidades/likec4-experto/evals/evals.json +69 -0
- package/habilidades/manejo-errores/.evolved.json +9 -0
- package/habilidades/manejo-errores/SKILL.md +407 -0
- package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
- package/habilidades/mapear-codebase/SKILL.md +275 -0
- package/habilidades/memoria-busqueda/SKILL.md +194 -0
- package/habilidades/memoria-busqueda/evals/evals.json +44 -0
- package/habilidades/meta-skills-estandar/SKILL.md +298 -0
- package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
- package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
- package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
- package/habilidades/microservicios/SKILL.md +155 -0
- package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
- package/habilidades/mobile-flutter/SKILL.md +199 -0
- package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
- package/habilidades/mobile-react-native/SKILL.md +176 -0
- package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
- package/habilidades/mongodb-experto/SKILL.md +302 -0
- package/habilidades/monitoring-alertas/SKILL.md +201 -0
- package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
- package/habilidades/nestjs-experto/SKILL.md +307 -0
- package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
- package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
- package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
- package/habilidades/nextjs-experto/SKILL.md +335 -0
- package/habilidades/nextjs-patrones/SKILL.md +303 -0
- package/habilidades/nextjs-testing/SKILL.md +331 -0
- package/habilidades/node-experto/.evolved.json +9 -0
- package/habilidades/node-experto/SKILL.md +266 -0
- package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
- package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
- package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
- package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
- package/habilidades/nuevo-proyecto/SKILL.md +204 -0
- package/habilidades/orquestacion-async/SKILL.md +303 -0
- package/habilidades/paid-media-tracking/SKILL.md +269 -0
- package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
- package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
- package/habilidades/patrones-python/SKILL.md +228 -0
- package/habilidades/patrones-python/evals/evals.json +56 -0
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
- package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
- package/habilidades/perfil-usuario/SKILL.md +200 -0
- package/habilidades/perfil-usuario/evals/evals.json +55 -0
- package/habilidades/performance-baseline/SKILL.md +297 -0
- package/habilidades/php-experto/SKILL.md +291 -0
- package/habilidades/php-patrones/SKILL.md +306 -0
- package/habilidades/php-testing/SKILL.md +280 -0
- package/habilidades/planear-fase/SKILL.md +269 -0
- package/habilidades/postgresql-experto/SKILL.md +151 -0
- package/habilidades/postgresql-experto/evals/evals.json +53 -0
- package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
- package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
- package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
- package/habilidades/privacy-memoria/SKILL.md +141 -0
- package/habilidades/privacy-memoria/evals/evals.json +43 -0
- package/habilidades/prompt-engineering/SKILL.md +518 -0
- package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
- package/habilidades/rag-arquitectura/SKILL.md +338 -0
- package/habilidades/rails-experto/SKILL.md +237 -0
- package/habilidades/rails-experto/recursos/active-record.md +260 -0
- package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
- package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
- package/habilidades/react-experto/SKILL.md +209 -0
- package/habilidades/react-experto/evals/evals.json +55 -0
- package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
- package/habilidades/react-optimizacion/SKILL.md +174 -0
- package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
- package/habilidades/redis-experto/SKILL.md +305 -0
- package/habilidades/release-semver/.evolved.json +9 -0
- package/habilidades/release-semver/SKILL.md +248 -0
- package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
- package/habilidades/rust-experto/SKILL.md +400 -0
- package/habilidades/rust-patrones/SKILL.md +296 -0
- package/habilidades/rust-testing/SKILL.md +311 -0
- package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
- package/habilidades/sql-optimizacion/SKILL.md +200 -0
- package/habilidades/sql-optimizacion/evals/evals.json +54 -0
- package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
- package/habilidades/sre-patrones/SKILL.md +333 -0
- package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
- package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
- package/habilidades/stripe-pagos/SKILL.md +550 -0
- package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
- package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
- package/habilidades/structured-outputs/SKILL.md +343 -0
- package/habilidades/swift-experto/SKILL.md +320 -0
- package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
- package/habilidades/swift-patrones/SKILL.md +313 -0
- package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
- package/habilidades/swift-testing/SKILL.md +254 -0
- package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
- package/habilidades/swl-dashboard/SKILL.md +370 -0
- package/habilidades/swl-markitdown/SKILL.md +285 -0
- package/habilidades/swl-markitdown/evals/evals.json +52 -0
- package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
- package/habilidades/tailwind-experto/SKILL.md +240 -0
- package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
- package/habilidades/tdd-workflow/SKILL.md +293 -0
- package/habilidades/terraform-experto/SKILL.md +321 -0
- package/habilidades/testing-python/SKILL.md +340 -0
- package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
- package/habilidades/threat-model-lite/SKILL.md +246 -0
- package/habilidades/tracing-processor/SKILL.md +212 -0
- package/habilidades/tracking-measurement/SKILL.md +239 -0
- package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
- package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
- package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
- package/habilidades/typescript-avanzado/SKILL.md +144 -0
- package/habilidades/typescript-avanzado/evals/evals.json +55 -0
- package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
- package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
- package/habilidades/ux-diseno/SKILL.md +116 -0
- package/habilidades/ux-diseno/evals/evals.json +43 -0
- package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
- package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
- package/habilidades/verificacion-evidencia/SKILL.md +160 -0
- package/habilidades/verificar-trabajo/SKILL.md +303 -0
- package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
- package/habilidades/wiki-conocimiento/SKILL.md +276 -0
- package/habilidades/wireframes-flujos/SKILL.md +212 -0
- package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
- package/habilidades/workflow-claude-code/SKILL.md +260 -0
- package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
- package/hooks/_run-hook.sh +57 -0
- package/hooks/actualizar-perfil-usuario.js +364 -0
- package/hooks/agente-lifecycle.js +71 -0
- package/hooks/aiisms-detector.js +173 -0
- package/hooks/audit-trail.js +204 -0
- package/hooks/auto-background.js +97 -0
- package/hooks/auto-consolidacion.js +178 -0
- package/hooks/auto-evolucion.js +666 -0
- package/hooks/auto-restaurar-settings.js +360 -0
- package/hooks/calidad-pre-commit.js +929 -0
- package/hooks/calidad-typescript.js +511 -0
- package/hooks/captura-feedback-usuario.js +148 -0
- package/hooks/check-update.js +211 -0
- package/hooks/clasificador-mensajes.js +271 -0
- package/hooks/degradacion-instintos.js +272 -0
- package/hooks/escaneo-secretos.js +389 -0
- package/hooks/extraccion-aprendizajes.js +763 -0
- package/hooks/grafo-contexto.js +129 -0
- package/hooks/graph-update.js +67 -0
- package/hooks/guardrail-modelo.js +247 -0
- package/hooks/inbox-aviso.js +75 -0
- package/hooks/inyeccion-contexto.js +246 -0
- package/hooks/lib/abort-registry.js +214 -0
- package/hooks/lib/agent-backend.js +210 -0
- package/hooks/lib/agent-comms.js +263 -0
- package/hooks/lib/agent-issue-codes.js +284 -0
- package/hooks/lib/agent-matcher.js +189 -0
- package/hooks/lib/async-hook-registry.js +252 -0
- package/hooks/lib/atomic-write.js +130 -0
- package/hooks/lib/auto-consolidator.js +335 -0
- package/hooks/lib/canary-skills.js +187 -0
- package/hooks/lib/consolidation-lock.js +291 -0
- package/hooks/lib/context-builder.js +430 -0
- package/hooks/lib/context-compressor.js +657 -0
- package/hooks/lib/convergence-detector.js +105 -0
- package/hooks/lib/delegation-tracker.js +198 -0
- package/hooks/lib/detectar-package-manager.js +423 -0
- package/hooks/lib/edit-accumulator.js +171 -0
- package/hooks/lib/error-classifier.js +308 -0
- package/hooks/lib/event-bus.js +112 -0
- package/hooks/lib/evolution-tracker.js +442 -0
- package/hooks/lib/execution-state.js +316 -0
- package/hooks/lib/fingerprint-id.js +135 -0
- package/hooks/lib/gateway-notify.js +116 -0
- package/hooks/lib/graph-security.js +75 -0
- package/hooks/lib/guardrail-metrics.js +202 -0
- package/hooks/lib/hook-circuit-breaker.js +206 -0
- package/hooks/lib/loop-detector.js +267 -0
- package/hooks/lib/mcp-health.js +184 -0
- package/hooks/lib/mcp-pool.js +436 -0
- package/hooks/lib/memory-search.js +506 -0
- package/hooks/lib/merkle-audit.js +96 -0
- package/hooks/lib/model-router.js +222 -0
- package/hooks/lib/normalize-error.js +324 -0
- package/hooks/lib/normalize-input.js +65 -0
- package/hooks/lib/nudge-tracker.js +306 -0
- package/hooks/lib/otlp-exporter.js +365 -0
- package/hooks/lib/performance-marks.js +239 -0
- package/hooks/lib/privacy-filter.js +128 -0
- package/hooks/lib/prompt-injection-scanner.js +209 -0
- package/hooks/lib/provenance-tracker.js +183 -0
- package/hooks/lib/rate-limit-tracker.js +253 -0
- package/hooks/lib/reflect-classifier.js +164 -0
- package/hooks/lib/resource-quota.js +122 -0
- package/hooks/lib/retry-jitter.js +165 -0
- package/hooks/lib/risk-engine.js +368 -0
- package/hooks/lib/run-log.js +408 -0
- package/hooks/lib/session-fts.js +379 -0
- package/hooks/lib/session-store.js +293 -0
- package/hooks/lib/singleton-guard.js +159 -0
- package/hooks/lib/skill-auditor.js +588 -0
- package/hooks/lib/sync-status.js +228 -0
- package/hooks/lib/taint-tracker.js +107 -0
- package/hooks/lib/task-service.js +295 -0
- package/hooks/lib/tech-skills-map.js +146 -0
- package/hooks/lib/telegram-cliente.js +159 -0
- package/hooks/lib/telegram-config.js +170 -0
- package/hooks/lib/token-budget.js +156 -0
- package/hooks/lib/token-estimator.js +420 -0
- package/hooks/lib/toon-compressor.js +245 -0
- package/hooks/lib/usage-model.js +183 -0
- package/hooks/lib/variable-resolver.js +230 -0
- package/hooks/linea-estado.js +324 -0
- package/hooks/metricas-evolucion.js +209 -0
- package/hooks/monitor-contexto.js +325 -0
- package/hooks/notificacion-sesion-stop.js +198 -0
- package/hooks/notificacion-telegram-notification.js +4 -0
- package/hooks/notificacion-telegram-subagent.js +4 -0
- package/hooks/notificacion-telegram.js +267 -0
- package/hooks/preservar-estado-pre-compact.js +150 -0
- package/hooks/proteccion-rutas.js +366 -0
- package/hooks/registro-turnos.js +209 -0
- package/hooks/resumen-sesion.js +249 -0
- package/hooks/risk-scoring.js +323 -0
- package/hooks/rotar-audit-auto.js +122 -0
- package/hooks/sugerir-regenerar-inventario.js +170 -0
- package/hooks/telemetria-agentes.js +167 -0
- package/hooks/tracking-costos.js +688 -0
- package/instintos/global.yaml +8 -0
- package/instintos/perfil-usuario.yaml +53 -0
- package/instintos/prompt-appendices.yaml +57 -0
- package/instintos/proyecto.yaml +372 -0
- package/manifiestos/gateway-config.json +77 -0
- package/manifiestos/handoff-context.json +223 -0
- package/manifiestos/hook-profiles.json +44 -0
- package/manifiestos/hooks-config.json +360 -0
- package/manifiestos/modulos.json +1173 -0
- package/manifiestos/perfiles.json +404 -0
- package/package.json +86 -0
- package/plantillas/ESTADO.md +109 -0
- package/plantillas/HOJA-RUTA.md +143 -0
- package/plantillas/PROYECTO.md +122 -0
- package/plantillas/REQUISITOS.md +132 -0
- package/plantillas/auditor-veto-template.md +105 -0
- package/plantillas/github-workflows/README.md +47 -0
- package/plantillas/github-workflows/release-please.yml +44 -0
- package/plantillas/github-workflows/swl-ci.yml +107 -0
- package/plantillas/github-workflows/swl-security.yml +51 -0
- package/plantillas/mcp-mineru.json +13 -0
- package/plantillas/research/ARQUITECTURA.md +220 -0
- package/plantillas/research/FUNCIONALIDADES.md +175 -0
- package/plantillas/research/RESUMEN.md +165 -0
- package/plantillas/research/STACK.md +233 -0
- package/plantillas/research/TRAMPAS.md +299 -0
- package/plantillas/skill-evals-template.json +44 -0
- package/plugin.json +343 -0
- package/reglas/accesibilidad.md +269 -0
- package/reglas/api-diseno.md +400 -0
- package/reglas/arquitectura.md +352 -0
- package/reglas/brevedad-output.md +124 -0
- package/reglas/cloud-infra.md +247 -0
- package/reglas/docs.md +245 -0
- package/reglas/estilo-codigo.md +201 -0
- package/reglas/git-workflow.md +245 -0
- package/reglas/gobernanza.md +271 -0
- package/reglas/harness-claude-code.md +213 -0
- package/reglas/hooks.md +186 -0
- package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
- package/reglas/lenguajes/csharp/hooks.md +281 -0
- package/reglas/lenguajes/csharp/patrones.md +226 -0
- package/reglas/lenguajes/csharp/seguridad.md +258 -0
- package/reglas/lenguajes/csharp/testing.md +176 -0
- package/reglas/lenguajes/go/estilo-codigo.md +195 -0
- package/reglas/lenguajes/go/hooks.md +249 -0
- package/reglas/lenguajes/go/patrones.md +249 -0
- package/reglas/lenguajes/go/seguridad.md +225 -0
- package/reglas/lenguajes/go/testing.md +272 -0
- package/reglas/lenguajes/java/estilo-codigo.md +217 -0
- package/reglas/lenguajes/java/hooks.md +251 -0
- package/reglas/lenguajes/java/patrones.md +226 -0
- package/reglas/lenguajes/java/seguridad.md +233 -0
- package/reglas/lenguajes/java/testing.md +238 -0
- package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
- package/reglas/lenguajes/kotlin/hooks.md +245 -0
- package/reglas/lenguajes/kotlin/patrones.md +201 -0
- package/reglas/lenguajes/kotlin/seguridad.md +202 -0
- package/reglas/lenguajes/kotlin/testing.md +236 -0
- package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
- package/reglas/lenguajes/nextjs/hooks.md +186 -0
- package/reglas/lenguajes/nextjs/patrones.md +225 -0
- package/reglas/lenguajes/nextjs/seguridad.md +216 -0
- package/reglas/lenguajes/nextjs/testing.md +193 -0
- package/reglas/lenguajes/php/estilo-codigo.md +228 -0
- package/reglas/lenguajes/php/hooks.md +165 -0
- package/reglas/lenguajes/php/patrones.md +233 -0
- package/reglas/lenguajes/php/seguridad.md +186 -0
- package/reglas/lenguajes/php/testing.md +205 -0
- package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
- package/reglas/lenguajes/rust/hooks.md +240 -0
- package/reglas/lenguajes/rust/patrones.md +250 -0
- package/reglas/lenguajes/rust/seguridad.md +221 -0
- package/reglas/lenguajes/rust/testing.md +194 -0
- package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
- package/reglas/lenguajes/swift/hooks.md +257 -0
- package/reglas/lenguajes/swift/patrones.md +235 -0
- package/reglas/lenguajes/swift/seguridad.md +248 -0
- package/reglas/lenguajes/swift/testing.md +242 -0
- package/reglas/markitdown.md +60 -0
- package/reglas/memoria-consolidada.md +209 -0
- package/reglas/patrones.md +225 -0
- package/reglas/performance.md +195 -0
- package/reglas/pruebas.md +159 -0
- package/reglas/seguridad-agentes.md +351 -0
- package/reglas/seguridad.md +151 -0
- package/reglas/skills-estandar.md +373 -0
- package/reglas/testing.md +193 -0
- package/schemas/agent-contract.json +176 -0
- package/schemas/agent-frontmatter.schema.json +149 -0
- package/schemas/agent-message.schema.json +53 -0
- package/schemas/agent-output-implementacion.schema.json +85 -0
- package/schemas/agent-output-planificacion.schema.json +113 -0
- package/schemas/agent-output-review.schema.json +78 -0
- package/schemas/diary-entry.schema.json +80 -0
- package/schemas/hook-profiles.schema.json +39 -0
- package/schemas/hooks-config.schema.json +74 -0
- package/schemas/instinct.schema.json +115 -0
- package/schemas/modulos.schema.json +29 -0
- package/schemas/perfiles.schema.json +28 -0
- package/schemas/plugin.schema.json +64 -0
- package/schemas/skill-evals.schema.json +95 -0
- package/schemas/skill-frontmatter.schema.json +170 -0
- package/scripts/actualizar.js +145 -0
- package/scripts/audit-skills.sh +78 -0
- package/scripts/auditar-agentes-gaps.js +149 -0
- package/scripts/auditar-cobertura-frameworks.js +241 -0
- package/scripts/auditar-skills-gaps.js +206 -0
- package/scripts/bootstrap-instintos.js +259 -0
- package/scripts/check-update.js +109 -0
- package/scripts/comandos/agents.js +105 -0
- package/scripts/comandos/info.js +108 -0
- package/scripts/comandos/install-asistido.js +186 -0
- package/scripts/comandos/skills.js +211 -0
- package/scripts/configurar-branch-protection.js +418 -0
- package/scripts/daemon-swl.py +388 -0
- package/scripts/desinstalar.js +130 -0
- package/scripts/doctor.js +559 -0
- package/scripts/field-report.js +199 -0
- package/scripts/generar-inventario.js +317 -0
- package/scripts/inbox-tmux-inject.js +161 -0
- package/scripts/inferir-herramientas-permitidas.js +586 -0
- package/scripts/inicializar.js +133 -0
- package/scripts/instalador.js +1031 -0
- package/scripts/instalar-git-hook.js +122 -0
- package/scripts/lib/agp-frontmatter.js +222 -0
- package/scripts/lib/append-con-marcadores.js +199 -0
- package/scripts/lib/artefactos-python.js +43 -0
- package/scripts/lib/audit-query.js +221 -0
- package/scripts/lib/autostart-linux.js +347 -0
- package/scripts/lib/autostart-macos.js +360 -0
- package/scripts/lib/autostart-windows.js +307 -0
- package/scripts/lib/budget-enforcer.js +252 -0
- package/scripts/lib/claude-sessions.js +285 -0
- package/scripts/lib/configurar-ci.js +380 -0
- package/scripts/lib/console-span-exporter.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -0
- package/scripts/lib/dashboard-widgets.js +290 -0
- package/scripts/lib/detectar-runtime.js +279 -0
- package/scripts/lib/detectar-stack.js +187 -0
- package/scripts/lib/diary-entry.js +234 -0
- package/scripts/lib/drift-detector.js +545 -0
- package/scripts/lib/estado.js +124 -0
- package/scripts/lib/gestor-componentes.js +243 -0
- package/scripts/lib/gitignore-manifest.js +305 -0
- package/scripts/lib/graph-analyze.py +556 -0
- package/scripts/lib/graph-builder.py +485 -0
- package/scripts/lib/graph-cluster.py +259 -0
- package/scripts/lib/health-row.js +168 -0
- package/scripts/lib/hooks-settings.js +789 -0
- package/scripts/lib/manifiestos.js +138 -0
- package/scripts/lib/mc-client.js +137 -0
- package/scripts/lib/notificaciones-telegram.js +1107 -0
- package/scripts/lib/npm-version.js +261 -0
- package/scripts/lib/paquetes-conocidos.js +50 -0
- package/scripts/lib/preservar-usuario.js +586 -0
- package/scripts/lib/prompt-builder.js +264 -0
- package/scripts/lib/resolver-externo.js +332 -0
- package/scripts/lib/schedule-parser.js +305 -0
- package/scripts/lib/scoring-instintos.js +240 -0
- package/scripts/lib/seguridad.js +160 -0
- package/scripts/lib/selector-interactivo.js +152 -0
- package/scripts/lib/semantic-search.js +242 -0
- package/scripts/lib/skill-discovery.js +234 -0
- package/scripts/lib/skill-metrics.js +246 -0
- package/scripts/lib/skill-normalizer.js +112 -0
- package/scripts/lib/skills-hub.js +340 -0
- package/scripts/lib/span-schema.js +134 -0
- package/scripts/lib/tool-cost-analyzer.js +255 -0
- package/scripts/lib/tracing-processor-interface.js +286 -0
- package/scripts/lib/transformadores/base.js +80 -0
- package/scripts/lib/transformadores/claude.js +124 -0
- package/scripts/lib/transformadores/codex.js +115 -0
- package/scripts/lib/transformadores/copilot.js +106 -0
- package/scripts/lib/transformadores/gemini.js +74 -0
- package/scripts/lib/transformadores/index.js +35 -0
- package/scripts/lib/transformadores/opencode.js +75 -0
- package/scripts/lib/ui.js +259 -0
- package/scripts/limpiar-artefactos-python.js +131 -0
- package/scripts/mcp-orchestrator.py +386 -0
- package/scripts/mcp-pool-manager.py +352 -0
- package/scripts/mcp-telemetry.py +378 -0
- package/scripts/poblar-evolvable.js +226 -0
- package/scripts/publicar.js +287 -0
- package/scripts/reflect-skills.js +403 -0
- package/scripts/rotar-audit-logs.js +185 -0
- package/scripts/run-skill-evals.js +242 -0
- package/scripts/smoke-test.js +374 -0
- package/scripts/token-analysis.py +471 -0
- package/scripts/validar-manifest.js +195 -0
- package/scripts/validar-memoria.js +321 -0
- package/scripts/validar-tests-aislamiento.js +184 -0
- package/scripts/validar-tokens-test.js +208 -0
- package/scripts/validar.js +147 -0
- package/scripts/validate-markdown.py +339 -0
- package/scripts/validate-skills.py +385 -0
- package/scripts/vendor/claude-usage/README.md +116 -0
- package/scripts/vendor/claude-usage/cli.py +334 -0
- package/scripts/vendor/claude-usage/dashboard.py +795 -0
- package/scripts/vendor/claude-usage/scanner.py +467 -0
- package/scripts/vendor/markitdown/cli.py +194 -0
- package/scripts/verificar-evolucion.js +289 -0
- package/scripts/verificar-release.js +494 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Daemon long-polling del bot de Telegram para swl-ses.
|
|
6
|
+
*
|
|
7
|
+
* SEGURIDAD:
|
|
8
|
+
* - Filtro hardcoded por TELEGRAM_CHAT_ID. Todo mensaje de otro chat_id
|
|
9
|
+
* recibe "Acceso denegado" y se registra en bot.log.
|
|
10
|
+
* - Whitelist git estricta: solo rev-parse, status, log, diff, branch.
|
|
11
|
+
* - Sin eval, exec ni shell habilitado. Solo execFileSync con array de argumentos.
|
|
12
|
+
* - Sin secretos en logs — token nunca se escribe en bot.log ni en respuestas.
|
|
13
|
+
* - Solo escribe en ~/.claude/notifications/ (offset, pid, log).
|
|
14
|
+
*
|
|
15
|
+
* Comandos heredados:
|
|
16
|
+
* /help /start /proyectos /estado /log /diff /ultimo /resumen
|
|
17
|
+
* /silencio /activar /mutes /quien
|
|
18
|
+
*
|
|
19
|
+
* Los comandos /inbox /costo /salud se agregan en Slice 007.
|
|
20
|
+
*
|
|
21
|
+
* @module bin/swl-telegram-bot
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const https = require('node:https');
|
|
25
|
+
const fs = require('node:fs');
|
|
26
|
+
const path = require('node:path');
|
|
27
|
+
const os = require('node:os');
|
|
28
|
+
|
|
29
|
+
const { cargarConfig } = require('../hooks/lib/telegram-config');
|
|
30
|
+
const { enviarMensaje } = require('../hooks/lib/telegram-cliente');
|
|
31
|
+
const { despachar } = require('./lib/bot-comandos');
|
|
32
|
+
|
|
33
|
+
// -----------------------------------------------------------------
|
|
34
|
+
// Configuración de paths de estado del daemon
|
|
35
|
+
// -----------------------------------------------------------------
|
|
36
|
+
const DIR_NOTIFICACIONES = path.join(os.homedir(), '.claude', 'notifications');
|
|
37
|
+
const RUTA_OFFSET = path.join(DIR_NOTIFICACIONES, 'bot.offset');
|
|
38
|
+
const RUTA_PID = path.join(DIR_NOTIFICACIONES, 'bot.pid');
|
|
39
|
+
const RUTA_LOG = path.join(DIR_NOTIFICACIONES, 'bot.log');
|
|
40
|
+
|
|
41
|
+
// -----------------------------------------------------------------
|
|
42
|
+
// Configuración de long-polling
|
|
43
|
+
// -----------------------------------------------------------------
|
|
44
|
+
const TIMEOUT_POLL_S = 50; // Timeout del request getUpdates (segundos)
|
|
45
|
+
const TIMEOUT_POLL_MS = (TIMEOUT_POLL_S + 5) * 1000; // +5s para timeout de red
|
|
46
|
+
const BACKOFF_INICIAL = 1000; // 1s
|
|
47
|
+
const BACKOFF_MAX_NORMAL = 16_000; // 16s
|
|
48
|
+
const BACKOFF_CIRCUIT = 60_000; // 60s — circuit breaker abierto
|
|
49
|
+
const MAX_FALLOS_CIRCUITO = 5;
|
|
50
|
+
|
|
51
|
+
// -----------------------------------------------------------------
|
|
52
|
+
// Estado del daemon
|
|
53
|
+
// -----------------------------------------------------------------
|
|
54
|
+
let fallosConsecutivos = 0;
|
|
55
|
+
let circuitAbierto = false;
|
|
56
|
+
let corriendo = true;
|
|
57
|
+
|
|
58
|
+
// -----------------------------------------------------------------
|
|
59
|
+
// Logger sin PII — token nunca se loggea
|
|
60
|
+
// -----------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Asegura que el directorio de notificaciones existe.
|
|
64
|
+
*/
|
|
65
|
+
function _asegurarDir() {
|
|
66
|
+
if (!fs.existsSync(DIR_NOTIFICACIONES)) {
|
|
67
|
+
fs.mkdirSync(DIR_NOTIFICACIONES, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Escribe una línea al log del bot.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} nivel - Nivel: INFO, WARN, ERROR.
|
|
75
|
+
* @param {string} mensaje - Mensaje sin secretos.
|
|
76
|
+
*/
|
|
77
|
+
function log(nivel, mensaje) {
|
|
78
|
+
const linea = `[${new Date().toISOString()}] [${nivel}] ${mensaje}\n`;
|
|
79
|
+
try {
|
|
80
|
+
_asegurarDir();
|
|
81
|
+
fs.appendFileSync(RUTA_LOG, linea, 'utf8');
|
|
82
|
+
} catch (_) {
|
|
83
|
+
// Si no se puede escribir el log, ignorar silenciosamente
|
|
84
|
+
}
|
|
85
|
+
// También imprimir a stderr para facilitar depuración al arrancar
|
|
86
|
+
process.stderr.write(linea);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// -----------------------------------------------------------------
|
|
90
|
+
// Gestión de offset persistente
|
|
91
|
+
// -----------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Lee el offset guardado en disco.
|
|
95
|
+
*
|
|
96
|
+
* @returns {number} El offset persistido, o 0 si no existe.
|
|
97
|
+
*/
|
|
98
|
+
function leerOffset() {
|
|
99
|
+
try {
|
|
100
|
+
if (fs.existsSync(RUTA_OFFSET)) {
|
|
101
|
+
const val = parseInt(fs.readFileSync(RUTA_OFFSET, 'utf8').trim(), 10);
|
|
102
|
+
if (!isNaN(val) && val >= 0) return val;
|
|
103
|
+
}
|
|
104
|
+
} catch (_) {}
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Guarda el offset en disco.
|
|
110
|
+
*
|
|
111
|
+
* @param {number} offset - El offset a persistir.
|
|
112
|
+
*/
|
|
113
|
+
function guardarOffset(offset) {
|
|
114
|
+
try {
|
|
115
|
+
_asegurarDir();
|
|
116
|
+
fs.writeFileSync(RUTA_OFFSET, String(offset), 'utf8');
|
|
117
|
+
} catch (err) {
|
|
118
|
+
log('WARN', `No se pudo guardar offset: ${err.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// -----------------------------------------------------------------
|
|
123
|
+
// Gestión del PID file
|
|
124
|
+
// -----------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Escribe el PID del proceso actual en el archivo pid.
|
|
128
|
+
*/
|
|
129
|
+
function escribirPid() {
|
|
130
|
+
try {
|
|
131
|
+
_asegurarDir();
|
|
132
|
+
fs.writeFileSync(RUTA_PID, String(process.pid), 'utf8');
|
|
133
|
+
} catch (err) {
|
|
134
|
+
log('WARN', `No se pudo escribir PID file: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Elimina el PID file al terminar el daemon.
|
|
140
|
+
*/
|
|
141
|
+
function eliminarPid() {
|
|
142
|
+
try {
|
|
143
|
+
if (fs.existsSync(RUTA_PID)) {
|
|
144
|
+
fs.unlinkSync(RUTA_PID);
|
|
145
|
+
}
|
|
146
|
+
} catch (_) {}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// -----------------------------------------------------------------
|
|
150
|
+
// Long-polling: getUpdates
|
|
151
|
+
// -----------------------------------------------------------------
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Llama a getUpdates de la API de Telegram.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} token - Token del bot.
|
|
157
|
+
* @param {number} offset - Offset para evitar procesar updates ya vistos.
|
|
158
|
+
* @returns {Promise<{ ok: boolean, updates: object[], error?: string }>}
|
|
159
|
+
*/
|
|
160
|
+
function getUpdates(token, offset) {
|
|
161
|
+
const payload = JSON.stringify({
|
|
162
|
+
offset,
|
|
163
|
+
timeout: TIMEOUT_POLL_S,
|
|
164
|
+
allowed_updates: ['message'],
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return new Promise((resolve) => {
|
|
168
|
+
const req = https.request(
|
|
169
|
+
{
|
|
170
|
+
method: 'POST',
|
|
171
|
+
hostname: 'api.telegram.org',
|
|
172
|
+
path: `/bot${token}/getUpdates`,
|
|
173
|
+
headers: {
|
|
174
|
+
'Content-Type': 'application/json',
|
|
175
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
176
|
+
},
|
|
177
|
+
timeout: TIMEOUT_POLL_MS,
|
|
178
|
+
},
|
|
179
|
+
(res) => {
|
|
180
|
+
let cuerpo = '';
|
|
181
|
+
res.on('data', (chunk) => { cuerpo += chunk; });
|
|
182
|
+
res.on('end', () => {
|
|
183
|
+
try {
|
|
184
|
+
const datos = JSON.parse(cuerpo);
|
|
185
|
+
if (datos.ok && Array.isArray(datos.result)) {
|
|
186
|
+
resolve({ ok: true, updates: datos.result, statusCode: res.statusCode });
|
|
187
|
+
} else {
|
|
188
|
+
resolve({ ok: false, updates: [], error: datos.description || 'respuesta no-ok', statusCode: res.statusCode });
|
|
189
|
+
}
|
|
190
|
+
} catch (parseErr) {
|
|
191
|
+
resolve({ ok: false, updates: [], error: `JSON inválido: ${parseErr.message}`, statusCode: res.statusCode });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
req.on('timeout', () => {
|
|
198
|
+
req.destroy();
|
|
199
|
+
resolve({ ok: false, updates: [], error: 'timeout', statusCode: 0 });
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
req.on('error', (err) => {
|
|
203
|
+
resolve({ ok: false, updates: [], error: err.message, statusCode: 0 });
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
req.write(payload);
|
|
207
|
+
req.end();
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// -----------------------------------------------------------------
|
|
212
|
+
// Pausa para backoff
|
|
213
|
+
// -----------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Pausa durante `ms` milisegundos.
|
|
217
|
+
*
|
|
218
|
+
* @param {number} ms - Milisegundos a esperar.
|
|
219
|
+
* @returns {Promise<void>}
|
|
220
|
+
*/
|
|
221
|
+
function esperar(ms) {
|
|
222
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Calcula el backoff exponencial con techo.
|
|
227
|
+
*
|
|
228
|
+
* @param {number} fallos - Número de fallos consecutivos.
|
|
229
|
+
* @returns {number} Milisegundos a esperar.
|
|
230
|
+
*/
|
|
231
|
+
function calcularBackoff(fallos) {
|
|
232
|
+
if (circuitAbierto) return BACKOFF_CIRCUIT;
|
|
233
|
+
const delay = BACKOFF_INICIAL * Math.pow(2, fallos - 1);
|
|
234
|
+
return Math.min(delay, BACKOFF_MAX_NORMAL);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// -----------------------------------------------------------------
|
|
238
|
+
// Procesamiento de un update individual
|
|
239
|
+
// -----------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Procesa un update recibido de getUpdates.
|
|
243
|
+
*
|
|
244
|
+
* @param {object} update - Update de Telegram.
|
|
245
|
+
* @param {string} token - Token del bot.
|
|
246
|
+
* @param {string} ownerChatId - Chat ID autorizado.
|
|
247
|
+
*/
|
|
248
|
+
async function procesarUpdate(update, token, ownerChatId) {
|
|
249
|
+
const mensaje = update.message;
|
|
250
|
+
if (!mensaje) return; // Ignorar updates sin message (edited_message, etc.)
|
|
251
|
+
|
|
252
|
+
const chatId = String(mensaje.chat?.id || '');
|
|
253
|
+
const texto = String(mensaje.text || '');
|
|
254
|
+
// Solo loggear los últimos 4 dígitos del chat_id para proteger PII
|
|
255
|
+
const chatIdOculto = chatId.length > 4 ? `***${chatId.slice(-4)}` : `***${chatId}`;
|
|
256
|
+
|
|
257
|
+
if (chatId !== String(ownerChatId)) {
|
|
258
|
+
log('WARN', `rechazado chat_id: ${chatIdOculto}`);
|
|
259
|
+
// Responder con acceso denegado
|
|
260
|
+
try {
|
|
261
|
+
await enviarMensaje(token, chatId, 'Acceso denegado');
|
|
262
|
+
} catch (_) {}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Extraer solo el nombre del comando para el log (no el texto completo por PII)
|
|
267
|
+
const primerToken = texto.trim().split(/\s+/)[0] || '';
|
|
268
|
+
const comandoLog = primerToken.startsWith('/') ? primerToken.split('@')[0] : '(mensaje)';
|
|
269
|
+
log('INFO', `comando recibido: ${comandoLog} de chat_id: ${chatIdOculto}`);
|
|
270
|
+
|
|
271
|
+
const { respuesta } = despachar(mensaje, ownerChatId);
|
|
272
|
+
|
|
273
|
+
if (!respuesta) return; // Mensaje sin comando — ignorar
|
|
274
|
+
|
|
275
|
+
try {
|
|
276
|
+
const resultado = await enviarMensaje(token, chatId, respuesta);
|
|
277
|
+
if (!resultado.ok) {
|
|
278
|
+
log('WARN', `fallo al enviar respuesta: ${resultado.error || resultado.statusCode}`);
|
|
279
|
+
}
|
|
280
|
+
} catch (err) {
|
|
281
|
+
log('ERROR', `excepción al enviar respuesta: ${err.message}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// -----------------------------------------------------------------
|
|
286
|
+
// Bucle principal del daemon
|
|
287
|
+
// -----------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Bucle principal de long-polling.
|
|
291
|
+
*
|
|
292
|
+
* @param {string} token - Token del bot.
|
|
293
|
+
* @param {string} ownerChatId - Chat ID autorizado.
|
|
294
|
+
*/
|
|
295
|
+
async function buclePolling(token, ownerChatId) {
|
|
296
|
+
let offset = leerOffset();
|
|
297
|
+
log('INFO', `daemon iniciado — PID ${process.pid} — offset inicial: ${offset}`);
|
|
298
|
+
|
|
299
|
+
while (corriendo) {
|
|
300
|
+
const resultado = await getUpdates(token, offset);
|
|
301
|
+
|
|
302
|
+
if (!resultado.ok) {
|
|
303
|
+
fallosConsecutivos++;
|
|
304
|
+
|
|
305
|
+
const esError4xx = resultado.statusCode >= 400 && resultado.statusCode < 500;
|
|
306
|
+
|
|
307
|
+
if (esError4xx) {
|
|
308
|
+
// Errores 4xx: credenciales inválidas u otro error cliente — fatal
|
|
309
|
+
log('ERROR', `error ${resultado.statusCode} de Telegram (cliente). Posible token inválido. Deteniendo daemon.`);
|
|
310
|
+
corriendo = false;
|
|
311
|
+
process.exitCode = 1;
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (fallosConsecutivos >= MAX_FALLOS_CIRCUITO) {
|
|
316
|
+
if (!circuitAbierto) {
|
|
317
|
+
log('WARN', `circuit breaker abierto tras ${fallosConsecutivos} fallos consecutivos. Backoff: ${BACKOFF_CIRCUIT / 1000}s`);
|
|
318
|
+
circuitAbierto = true;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const backoff = calcularBackoff(fallosConsecutivos);
|
|
323
|
+
log('WARN', `fallo getUpdates (${fallosConsecutivos}/${MAX_FALLOS_CIRCUITO}): ${resultado.error}. Reintentando en ${backoff}ms`);
|
|
324
|
+
|
|
325
|
+
if (corriendo) await esperar(backoff);
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Éxito: resetear contadores de fallo
|
|
330
|
+
if (fallosConsecutivos > 0) {
|
|
331
|
+
log('INFO', `conexión restaurada tras ${fallosConsecutivos} fallos`);
|
|
332
|
+
fallosConsecutivos = 0;
|
|
333
|
+
circuitAbierto = false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Procesar cada update
|
|
337
|
+
for (const update of resultado.updates) {
|
|
338
|
+
if (!corriendo) break;
|
|
339
|
+
try {
|
|
340
|
+
await procesarUpdate(update, token, ownerChatId);
|
|
341
|
+
} catch (err) {
|
|
342
|
+
log('ERROR', `error inesperado procesando update ${update.update_id}: ${err.message}`);
|
|
343
|
+
}
|
|
344
|
+
// Avanzar offset: update_id + 1 para marcar como procesado
|
|
345
|
+
if (typeof update.update_id === 'number') {
|
|
346
|
+
offset = update.update_id + 1;
|
|
347
|
+
guardarOffset(offset);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// -----------------------------------------------------------------
|
|
354
|
+
// Cleanup en señales de terminación
|
|
355
|
+
// -----------------------------------------------------------------
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Handler de shutdown limpio.
|
|
359
|
+
*
|
|
360
|
+
* @param {string} señal - Nombre de la señal recibida.
|
|
361
|
+
*/
|
|
362
|
+
function cleanup(señal) {
|
|
363
|
+
log('INFO', `señal ${señal} recibida — apagando daemon`);
|
|
364
|
+
corriendo = false;
|
|
365
|
+
eliminarPid();
|
|
366
|
+
process.exit(0);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
process.on('SIGTERM', () => cleanup('SIGTERM'));
|
|
370
|
+
process.on('SIGINT', () => cleanup('SIGINT'));
|
|
371
|
+
|
|
372
|
+
process.on('uncaughtException', (err) => {
|
|
373
|
+
log('ERROR', `uncaughtException: ${err.message}\n${err.stack || ''}`);
|
|
374
|
+
eliminarPid();
|
|
375
|
+
process.exit(1);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
process.on('unhandledRejection', (reason) => {
|
|
379
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
380
|
+
log('ERROR', `unhandledRejection: ${msg}`);
|
|
381
|
+
// No terminar — best-effort
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// -----------------------------------------------------------------
|
|
385
|
+
// Punto de entrada
|
|
386
|
+
// -----------------------------------------------------------------
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Arranca el daemon de Telegram.
|
|
390
|
+
* Separado para facilitar tests de importación sin efecto lateral.
|
|
391
|
+
*/
|
|
392
|
+
async function runDaemon() {
|
|
393
|
+
// Verificar credenciales
|
|
394
|
+
const { config, valido, errores } = cargarConfig();
|
|
395
|
+
|
|
396
|
+
if (!valido) {
|
|
397
|
+
process.stderr.write(
|
|
398
|
+
`[ERROR] Faltan credenciales de Telegram: ${errores.join(', ')}\n` +
|
|
399
|
+
`Configura ~/.claude/notifications/.env con TELEGRAM_BOT_TOKEN y TELEGRAM_CHAT_ID.\n` +
|
|
400
|
+
`Puedes usar /swl:notificaciones init para configurarlas.\n`
|
|
401
|
+
);
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const token = config.TELEGRAM_BOT_TOKEN;
|
|
406
|
+
const ownerChatId = String(config.TELEGRAM_CHAT_ID).trim();
|
|
407
|
+
|
|
408
|
+
// Escribir PID file
|
|
409
|
+
_asegurarDir();
|
|
410
|
+
escribirPid();
|
|
411
|
+
|
|
412
|
+
try {
|
|
413
|
+
await buclePolling(token, ownerChatId);
|
|
414
|
+
} finally {
|
|
415
|
+
eliminarPid();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Patrón dual-use: librería importable para tests + CLI ejecutable
|
|
420
|
+
if (require.main === module) {
|
|
421
|
+
runDaemon().catch((err) => {
|
|
422
|
+
log('ERROR', `error fatal en daemon: ${err.message}`);
|
|
423
|
+
eliminarPid();
|
|
424
|
+
process.exit(1);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
module.exports = {
|
|
429
|
+
// Exportar funciones puras para tests
|
|
430
|
+
leerOffset,
|
|
431
|
+
guardarOffset,
|
|
432
|
+
getUpdates,
|
|
433
|
+
procesarUpdate,
|
|
434
|
+
cleanup,
|
|
435
|
+
esperar,
|
|
436
|
+
calcularBackoff,
|
|
437
|
+
// Para tests de integración
|
|
438
|
+
runDaemon,
|
|
439
|
+
RUTA_OFFSET,
|
|
440
|
+
RUTA_PID,
|
|
441
|
+
RUTA_LOG,
|
|
442
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>Label</key>
|
|
6
|
+
<string>com.swl.telegram-bot</string>
|
|
7
|
+
<key>ProgramArguments</key>
|
|
8
|
+
<array>
|
|
9
|
+
<string>{{NODE_PATH}}</string>
|
|
10
|
+
<string>{{BIN_PATH}}</string>
|
|
11
|
+
</array>
|
|
12
|
+
<key>RunAtLoad</key>
|
|
13
|
+
<true/>
|
|
14
|
+
<key>KeepAlive</key>
|
|
15
|
+
<true/>
|
|
16
|
+
<key>StandardOutPath</key>
|
|
17
|
+
<string>{{HOME}}/.claude/notifications/bot.stdout.log</string>
|
|
18
|
+
<key>StandardErrorPath</key>
|
|
19
|
+
<string>{{HOME}}/.claude/notifications/bot.stderr.log</string>
|
|
20
|
+
</dict>
|
|
21
|
+
</plist>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SWL Telegram Bot Daemon
|
|
3
|
+
After=network-online.target
|
|
4
|
+
|
|
5
|
+
[Service]
|
|
6
|
+
Type=simple
|
|
7
|
+
ExecStart={{NODE_PATH}} {{BIN_PATH}}
|
|
8
|
+
Restart=on-failure
|
|
9
|
+
RestartSec=5s
|
|
10
|
+
StandardOutput=append:{{HOME}}/.claude/notifications/bot.stdout.log
|
|
11
|
+
StandardError=append:{{HOME}}/.claude/notifications/bot.stderr.log
|
|
12
|
+
|
|
13
|
+
[Install]
|
|
14
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"release.md": {
|
|
3
|
+
"evolved": true,
|
|
4
|
+
"evolvedFrom": "5.4.0",
|
|
5
|
+
"evolvedAt": "2026-04-11",
|
|
6
|
+
"evolvedBy": "aprender",
|
|
7
|
+
"evolvedNote": "mejora de metodología: checklist obligatoria de archivos de versión en paso 6"
|
|
8
|
+
},
|
|
9
|
+
"aprender.md": {
|
|
10
|
+
"evolved": true,
|
|
11
|
+
"evolvedFrom": "5.12.3",
|
|
12
|
+
"evolvedAt": "2026-04-25",
|
|
13
|
+
"evolvedBy": "aprender",
|
|
14
|
+
"evolvedNote": "Paso 2 — filtro crítico obligatorio sobre reportes de sub-agentes Explore para evitar sobre-ingeniería al analizar papers académicos"
|
|
15
|
+
},
|
|
16
|
+
"verificar.md": {
|
|
17
|
+
"evolved": true,
|
|
18
|
+
"evolvedFrom": "5.12.3",
|
|
19
|
+
"evolvedAt": "2026-04-26",
|
|
20
|
+
"evolvedBy": "evolucionar",
|
|
21
|
+
"evolvedNote": "flag --until-converge para iterar verificar→corregir→re-verificar hasta 0 hallazgos CRÍTICO+ALTO+MAYOR (max-iter=5, --no-prompt CI, detección adversarial ≥5 hallazgos nuevos)"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swl:actualizar
|
|
3
|
+
description: Actualiza el sistema SWL a la última versión disponible. Detecta automáticamente el perfil instalado y re-instala con --force preservando la configuración del usuario. No requiere desinstalar primero.
|
|
4
|
+
allowed_tools: ["Read", "Bash", "Glob"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /swl:actualizar — Actualizar sistema SWL
|
|
8
|
+
|
|
9
|
+
Eres el actualizador del sistema SWL dentro de Claude Code. Tu misión es actualizar los componentes instalados a la última versión disponible sin perder la configuración del usuario ni requerir desinstalación previa.
|
|
10
|
+
|
|
11
|
+
## Cuándo usar este comando
|
|
12
|
+
|
|
13
|
+
- Cuando se publicó una nueva versión del sistema SWL y quieres obtener las mejoras
|
|
14
|
+
- Después de que `/swl:salud` reporta que la versión instalada está desactualizada
|
|
15
|
+
- Cuando otro miembro del equipo indica que hay actualización disponible
|
|
16
|
+
- Para re-instalar el mismo perfil después de modificaciones manuales que dejaron el sistema inconsistente
|
|
17
|
+
|
|
18
|
+
No usar si SWL no está instalado — en ese caso usar `/swl:instalar`.
|
|
19
|
+
|
|
20
|
+
## Paso 0 — Verificar que SWL está instalado
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cat .claude/.swl-install-state.json 2>/dev/null
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Si NO existe archivo de estado:
|
|
27
|
+
- Informa: "No se encontró una instalación de SWL en este proyecto."
|
|
28
|
+
- Sugiere: "Usa `/swl:instalar` para instalar SWL por primera vez."
|
|
29
|
+
- DETENTE.
|
|
30
|
+
|
|
31
|
+
Si existe, extrae:
|
|
32
|
+
- `perfil`: el perfil actualmente instalado
|
|
33
|
+
- `versionSistema`: la versión instalada
|
|
34
|
+
- `global`: si fue instalación global
|
|
35
|
+
- `archivosInstalados`: cantidad de archivos
|
|
36
|
+
|
|
37
|
+
Informa al usuario:
|
|
38
|
+
```
|
|
39
|
+
SWL instalado:
|
|
40
|
+
Versión: <versionSistema>
|
|
41
|
+
Perfil: <perfil>
|
|
42
|
+
Archivos: <N>
|
|
43
|
+
Tipo: <local|global>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Paso 1 — Verificar versión disponible
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm view @saulwade/swl-ses version 2>/dev/null \
|
|
50
|
+
|| npm view @saul-wade/swl-ses version --registry=https://npm.pkg.github.com 2>/dev/null
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Si hay una versión más nueva, informa:
|
|
54
|
+
- "Versión instalada: **X**. Versión disponible: **Y**."
|
|
55
|
+
|
|
56
|
+
Si ya está en la última versión:
|
|
57
|
+
- "Ya tienes la última versión (**X**). ¿Deseas re-instalar de todos modos?"
|
|
58
|
+
- Si el usuario dice no, DETENTE.
|
|
59
|
+
|
|
60
|
+
## Paso 1.5 — Descubrimiento de features nuevas
|
|
61
|
+
|
|
62
|
+
Cuando hay una versión nueva disponible, mostrar qué cambió entre la versión
|
|
63
|
+
instalada y la disponible para que el usuario tome una decisión informada.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Obtener changelog entre versiones (si está disponible localmente o via npm)
|
|
67
|
+
CURRENT="<version_instalada>"
|
|
68
|
+
AVAILABLE="<version_disponible>"
|
|
69
|
+
|
|
70
|
+
# Opción 1: Si el repo SWL está disponible como referencia
|
|
71
|
+
if [ -f "CHANGELOG.md" ]; then
|
|
72
|
+
# Extraer entradas del changelog entre las dos versiones
|
|
73
|
+
sed -n "/## \[$AVAILABLE\]/,/## \[$CURRENT\]/p" CHANGELOG.md | head -50
|
|
74
|
+
fi
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Presentar al usuario un resumen categorizado:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
=== Novedades entre v<CURRENT> y v<AVAILABLE> ===
|
|
81
|
+
|
|
82
|
+
📦 Componentes nuevos:
|
|
83
|
+
- [agentes/skills/hooks/comandos nuevos]
|
|
84
|
+
|
|
85
|
+
🔧 Mejoras:
|
|
86
|
+
- [mejoras a componentes existentes]
|
|
87
|
+
|
|
88
|
+
🐛 Correcciones:
|
|
89
|
+
- [bugs corregidos]
|
|
90
|
+
|
|
91
|
+
⚠ Cambios que requieren atención:
|
|
92
|
+
- [breaking changes o migraciones necesarias]
|
|
93
|
+
- [reglas nuevas obligatorias]
|
|
94
|
+
- [hooks nuevos que podrían afectar el flujo]
|
|
95
|
+
|
|
96
|
+
💡 Guía de migración:
|
|
97
|
+
- [Si hay cambios breaking, pasos concretos para adaptar el proyecto]
|
|
98
|
+
- [Si hay hooks nuevos, cómo configurarlos]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Si no se puede obtener el changelog, informar:
|
|
102
|
+
```
|
|
103
|
+
No se pudo obtener el detalle de cambios entre versiones.
|
|
104
|
+
Consulta el CHANGELOG.md del repositorio SWL para ver las novedades.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Paso 2 — Confirmar actualización
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
=== Actualización SWL ===
|
|
111
|
+
|
|
112
|
+
Versión actual: <version instalada>
|
|
113
|
+
Versión disponible: <version nueva>
|
|
114
|
+
Perfil: <perfil>
|
|
115
|
+
Tipo: <local|global>
|
|
116
|
+
|
|
117
|
+
La actualización:
|
|
118
|
+
- Sobrescribe agentes, skills, comandos, reglas y hooks
|
|
119
|
+
- Actualiza hooks en settings.json
|
|
120
|
+
- Preserva _userland/ (extensiones del usuario)
|
|
121
|
+
- Preserva .planning/ (estado del proyecto)
|
|
122
|
+
|
|
123
|
+
¿Proceder?
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Espera confirmación del usuario.
|
|
127
|
+
|
|
128
|
+
## Paso 3 — Ejecutar actualización
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx @saulwade/swl-ses@latest install --target claude --profile <PERFIL> [--global] --force
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Usa el mismo perfil y ubicación de la instalación original.
|
|
135
|
+
|
|
136
|
+
## Paso 4 — Ejecutar doctor
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx @saulwade/swl-ses@latest doctor
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Paso 5 — Reportar resultado
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
=== Actualización SWL completada ===
|
|
146
|
+
|
|
147
|
+
Versión anterior: <X>
|
|
148
|
+
Versión nueva: <Y>
|
|
149
|
+
Perfil: <perfil>
|
|
150
|
+
Archivos: <N> actualizados
|
|
151
|
+
|
|
152
|
+
Doctor: <resultado>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Cambio de perfil durante actualización
|
|
156
|
+
|
|
157
|
+
Si el usuario dice algo como "actualiza y cambia a perfil completo", ejecuta:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx @saulwade/swl-ses@latest install --target claude --profile <NUEVO_PERFIL> [--global] --force
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Informa que el cambio de perfil puede agregar componentes nuevos pero no elimina los del perfil anterior. Si quiere una instalación limpia con otro perfil, sugiere:
|
|
164
|
+
1. `npx swl-ses uninstall --target claude`
|
|
165
|
+
2. `/swl:instalar` con el nuevo perfil
|
|
166
|
+
|
|
167
|
+
## Reglas de comportamiento
|
|
168
|
+
|
|
169
|
+
- SIEMPRE verifica que SWL está instalado antes de intentar actualizar.
|
|
170
|
+
- SIEMPRE muestra versión actual vs disponible.
|
|
171
|
+
- SIEMPRE confirma antes de ejecutar.
|
|
172
|
+
- NUNCA cambia el perfil sin que el usuario lo pida explícitamente.
|
|
173
|
+
- Preserva `_userland/` y `.planning/` siempre.
|
|
174
|
+
- Si la actualización falla, el sistema queda en el estado anterior (los archivos existentes no se borran antes de copiar los nuevos).
|