@saulwade/swl-ses 2.3.0 → 2.3.1
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 +47 -6
- package/README.md +1 -1
- package/agentes/accesibilidad-wcag-swl.md +690 -690
- package/agentes/arquitecto-swl.md +267 -267
- package/agentes/auto-evolucion-swl.md +908 -908
- package/agentes/backend-api-swl.md +472 -472
- 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-node-swl.md +479 -479
- package/agentes/backend-python-swl.md +605 -605
- 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/datos-swl.md +605 -605
- 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/gh-fix-ci-swl.md +2 -2
- package/agentes/implementador-swl.md +328 -328
- package/agentes/investigador-swl.md +432 -432
- package/agentes/investigador-ux-swl.md +505 -505
- package/agentes/llm-apps-swl.md +278 -278
- 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/notificador-swl.md +918 -918
- package/agentes/observabilidad-swl.md +438 -438
- package/agentes/orquestador-swl.md +1026 -1026
- 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 +1 -1
- package/agentes/release-manager-swl.md +590 -590
- package/agentes/rendimiento-swl.md +713 -713
- package/agentes/resolutor-build-swl.md +245 -245
- package/agentes/revisor-angular-swl.md +278 -278
- package/agentes/revisor-codigo-swl.md +505 -505
- 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/sre-swl.md +291 -291
- package/agentes/tdd-qa-swl.md +393 -393
- package/comandos/swl/briefing.md +119 -119
- package/comandos/swl/contribuir.md +233 -233
- package/comandos/swl/predecir.md +139 -139
- package/comandos/swl/sesiones.md +1 -1
- package/gateway/agent-executor.js +1 -1
- package/gateway/lib/event-channel.js +191 -191
- package/habilidades/agent-deep-links/SKILL.md +148 -148
- package/habilidades/agentes-como-servicio/SKILL.md +2 -2
- package/habilidades/angular-moderno/SKILL.md +20 -1
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -276
- package/habilidades/backend-async-postgres-testing/SKILL.md +215 -215
- package/habilidades/backend-error-design/SKILL.md +221 -221
- package/habilidades/backend-production-resilience/SKILL.md +288 -288
- package/habilidades/benchmark-memoria/SKILL.md +186 -186
- package/habilidades/calidad-anti-patrones-universales/SKILL.md +368 -368
- package/habilidades/calidad-contract-testing/SKILL.md +165 -165
- package/habilidades/calidad-mutation-testing/SKILL.md +170 -170
- package/habilidades/changelog-generator/scripts/parse-commits.js +367 -367
- package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
- package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
- package/habilidades/drift-detection/SKILL.md +179 -179
- package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +1 -1
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
- package/habilidades/eval-framework/SKILL.md +212 -212
- package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
- package/habilidades/harness-claude-code/recursos/disciplina-harness-regla.md +252 -252
- package/habilidades/legacy-code-rescue/SKILL.md +267 -267
- 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/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
- package/habilidades/proceso-ddia-fundamentos/SKILL.md +255 -255
- package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
- package/habilidades/proceso-debate-adversarial/recursos/personas.md +105 -105
- package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
- package/habilidades/proceso-dynamic-workflows/SKILL.md +138 -138
- 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-intent-engineering/SKILL.md +269 -269
- package/habilidades/proceso-modular-split/SKILL.md +256 -256
- package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +2 -2
- package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
- package/habilidades/structured-outputs/SKILL.md +2 -2
- 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/swl-dashboard/SKILL.md +2 -2
- package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
- package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +1 -1
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +1 -1
- package/hooks/ciclo-evolucion-subagente.js +26 -26
- package/hooks/ciclo-evolucion.js +26 -26
- package/hooks/claudemd-bloat-detector.js +161 -161
- package/hooks/claudemd-duplicacion-detector.js +170 -170
- package/hooks/contexto-iteracion.js +144 -144
- package/hooks/guardrail-modelo.js +1 -1
- package/hooks/lib/agent-routing.js +107 -107
- package/hooks/lib/auto-consolidator.js +335 -335
- package/hooks/lib/autonomia.js +208 -208
- 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-auto-evolucion.js +701 -701
- package/hooks/lib/etapa-metricas.js +388 -388
- package/hooks/lib/etapa-perfil-usuario.js +376 -376
- package/hooks/lib/loop-telemetry.js +321 -321
- package/hooks/lib/merkle-audit.js +96 -96
- package/hooks/lib/model-router.js +2 -2
- package/hooks/lib/propose-step.js +358 -358
- package/hooks/lib/provenance-tracker.js +191 -191
- package/hooks/lib/rate-limit-tracker.js +253 -253
- package/hooks/lib/resource-quota.js +122 -122
- package/hooks/lib/retry-jitter.js +165 -165
- package/hooks/lib/security-net.js +201 -201
- package/hooks/lib/skill-auditor.js +588 -588
- package/hooks/lib/sync-status.js +228 -228
- package/hooks/lib/taint-tracker.js +107 -107
- package/hooks/lib/text-similarity.js +241 -241
- package/hooks/lib/token-estimator.js +1 -0
- package/hooks/lib/toon-compressor.js +245 -245
- package/hooks/lib/usage-model.js +1 -1
- package/hooks/linea-estado.js +2 -0
- package/hooks/registro-turnos.js +209 -209
- package/hooks/session-briefing.js +98 -98
- package/hooks/spec-gate.js +211 -211
- package/hooks/sugerir-regenerar-inventario.js +170 -170
- package/hooks/tdd-gate.js +241 -241
- package/hooks/telemetria-skill-routing.js +100 -100
- package/hooks/validar-formato-post-subagente.js +140 -140
- package/hooks/validar-intent-spec.js +242 -242
- package/hooks/validar-memoria-hook.js +218 -218
- package/hooks/validar-planning-paths.js +134 -134
- 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 +2291 -1964
- package/manifiestos/planning-paths.json +44 -44
- package/manifiestos/skills-lock.json +1282 -1282
- package/package.json +1 -1
- package/plantillas/auditor-veto-template.md +105 -105
- package/plantillas/github-workflows/README.md +47 -47
- package/plantillas/github-workflows/release-please.yml +44 -44
- package/plantillas/github-workflows/swl-ci.yml +107 -107
- package/plantillas/github-workflows/swl-security.yml +51 -51
- package/plugin.json +1 -1
- package/reglas/accesibilidad.md +10 -10
- package/reglas/analisis-previo-tareas-grandes.md +172 -172
- package/reglas/api-diseno.md +9 -9
- package/reglas/arreglar-al-detectar.md +240 -240
- 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/debatir-antes-de-aceptar.md +158 -158
- package/reglas/fragmentos-compartidos.md +183 -183
- package/reglas/hooks.md +6 -6
- package/reglas/intent-engineering.md +218 -218
- package/reglas/markitdown.md +8 -8
- package/reglas/monitor-ci.md +309 -309
- package/reglas/patrones.md +6 -6
- package/reglas/sesiones-paralelas.md +180 -180
- package/reglas/sin-duplicacion-reglas-globales.md +182 -182
- package/reglas/skills-estandar.md +6 -6
- package/reglas/testing.md +7 -7
- package/reglas/tests-cleanup.md +224 -224
- package/reglas/usar-code-review-graph.md +155 -155
- package/reglas/usar-context7.md +226 -226
- package/reglas/verificar-citas-normativas.md +548 -548
- package/schemas/agent-frontmatter.schema.json +3 -3
- 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/hook-profiles.schema.json +54 -54
- package/schemas/hooks-config.schema.json +89 -89
- package/schemas/modulos.schema.json +38 -38
- package/schemas/perfiles.schema.json +36 -36
- package/schemas/plugin.schema.json +77 -77
- package/schemas/skill-evals.schema.json +119 -119
- package/schemas/skill-frontmatter.schema.json +245 -245
- 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/benchmark-memoria.js +167 -167
- package/scripts/cli/aprobar-plan.js +73 -73
- package/scripts/cli/briefing.js +23 -23
- package/scripts/cli/ciclo-evolucion.js +26 -26
- package/scripts/cli/configurar-ci.js +40 -40
- 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/liberar-fase.js +42 -42
- package/scripts/cli/loop-telemetry.js +125 -125
- package/scripts/cli/mark-evolved.js +56 -56
- 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/propose-step.js +29 -29
- 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/configurar-branch-protection.js +418 -418
- package/scripts/detectar-aprendizajes-duplicados.js +151 -151
- package/scripts/field-report.js +199 -199
- package/scripts/generar-checklists-consolidados.js +273 -273
- package/scripts/generar-matriz-lenguajes.js +271 -271
- package/scripts/lib/artefactos-python.js +43 -43
- package/scripts/lib/auditar-invocaciones-comandos.js +104 -104
- package/scripts/lib/benchmark-metrics.js +160 -160
- package/scripts/lib/budget-enforcer.js +252 -252
- package/scripts/lib/ci-reader.js +193 -193
- package/scripts/lib/claude-sessions.js +1 -0
- package/scripts/lib/configurar-ci.js +380 -380
- package/scripts/lib/contadores-inventario.js +217 -217
- package/scripts/lib/detectar-host-swl.js +175 -175
- 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/diary-entry.js +234 -234
- package/scripts/lib/eval-metrics-store.js +218 -218
- package/scripts/lib/eval-quality.js +171 -171
- package/scripts/lib/eval-schemas.js +144 -144
- package/scripts/lib/eval-self-correct.js +106 -106
- package/scripts/lib/eval-validator.js +185 -185
- package/scripts/lib/evidencia-release.js +322 -322
- package/scripts/lib/expandir-targets.js +71 -71
- package/scripts/lib/gate-hooks-requires.js +249 -249
- package/scripts/lib/gate-licencias.js +212 -212
- package/scripts/lib/git-metricas.js +257 -257
- package/scripts/lib/jaccard-similarity.js +98 -98
- package/scripts/lib/longmemeval-runner.js +125 -125
- package/scripts/lib/metricas-dora.js +204 -204
- package/scripts/lib/npm-version.js +261 -261
- package/scripts/lib/paquetes-conocidos.js +50 -50
- package/scripts/lib/plan-lock.js +275 -275
- package/scripts/lib/pr-analyzer.js +399 -399
- package/scripts/lib/prompt-builder.js +264 -264
- package/scripts/lib/reglas-globales-conocidas.json +180 -180
- package/scripts/lib/resolver-plan-fase.js +37 -37
- package/scripts/lib/rrf-fusion.js +175 -175
- package/scripts/lib/schema-version.js +164 -164
- package/scripts/lib/scoring-instintos.js +277 -277
- package/scripts/lib/semantic-search.js +252 -252
- package/scripts/lib/toml-merge.js +204 -204
- package/scripts/lib/tool-cost-analyzer.js +1 -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/publicar.js +497 -497
- package/scripts/run-eval.js +141 -141
- 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/index.js +162 -162
- 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/inspect.js +173 -173
- package/scripts/tui/pantallas/install-wizard.js +334 -334
- 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/tui/pantallas/uninstall-wizard.js +208 -208
- package/scripts/tui/pantallas/update-wizard.js +232 -232
- package/scripts/tui/pantallas/welcome.js +187 -187
- package/scripts/validar-userland-vacio.js +110 -110
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Hook: telemetria-skill-routing.js
|
|
6
|
-
* Tipo: PostToolUse (matcher: "Skill")
|
|
7
|
-
*
|
|
8
|
-
* Cablea la lib huérfana `scripts/lib/skill-metrics.js`: por cada invocación
|
|
9
|
-
* del tool Skill registra la frecuencia/estado en `.planning/skill-metrics.json`
|
|
10
|
-
* vía `registrarUso(cwd, skillName, estado, duracionMs)`.
|
|
11
|
-
*
|
|
12
|
-
* Propósito (Revisión Evolutiva 04, P-2 "bloat y precisión de routing"):
|
|
13
|
-
* acumular telemetría de qué skills se invocan para alimentar la futura
|
|
14
|
-
* auditoría de bloat (skills muertos / solapados). Es la instrumentación que
|
|
15
|
-
* el roadmap permite adelantar como "tarea suelta" antes de la fase de auditoría.
|
|
16
|
-
*
|
|
17
|
-
* Distinto de telemetria-agentes.js (spans OTLP a traces/) y de audit-trail.js
|
|
18
|
-
* (todos los tool calls a audit.jsonl): este hook produce el agregado por-skill
|
|
19
|
-
* que la auditoría de bloat necesita y que ningún otro hook genera.
|
|
20
|
-
*
|
|
21
|
-
* NUNCA bloquea (siempre exit 0). Async: corre en background.
|
|
22
|
-
* Opt-out: SWL_SKILL_TELEMETRIA=0.
|
|
23
|
-
*
|
|
24
|
-
* Origen: punto P-2 de la Revisión Evolutiva 04 (instrumentación adelantada).
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Extrae el evento de skill de un payload PostToolUse.
|
|
29
|
-
* Pura y testeable — no toca el filesystem.
|
|
30
|
-
*
|
|
31
|
-
* @param {object} data payload PostToolUse
|
|
32
|
-
* @returns {{skillName: string, estado: 'ok'|'error'}|null} null si no aplica
|
|
33
|
-
*/
|
|
34
|
-
function extraerEvento(data) {
|
|
35
|
-
if (!data || typeof data !== 'object') return null;
|
|
36
|
-
const toolName = String(data.tool_name || (data.tool && data.tool.name) || '');
|
|
37
|
-
if (toolName !== 'Skill') return null;
|
|
38
|
-
|
|
39
|
-
const input = data.tool_input || {};
|
|
40
|
-
const skillName = String(input.skill || input.name || '').trim();
|
|
41
|
-
if (!skillName) return null;
|
|
42
|
-
|
|
43
|
-
const esError = Boolean(data.error_message || data.error);
|
|
44
|
-
return { skillName, estado: esError ? 'error' : 'ok' };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Carga defensiva de la lib de métricas. Si no está disponible (destino
|
|
49
|
-
* aplanado, instalación parcial), retorna null y el hook degrada en silencio.
|
|
50
|
-
* @returns {Function|null} registrarUso o null
|
|
51
|
-
*/
|
|
52
|
-
function cargarRegistrar() {
|
|
53
|
-
try {
|
|
54
|
-
return require('../scripts/lib/skill-metrics').registrarUso;
|
|
55
|
-
} catch (_) {
|
|
56
|
-
try {
|
|
57
|
-
return require('./lib/skill-metrics').registrarUso;
|
|
58
|
-
} catch (_2) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Procesa un payload y registra el uso del skill si aplica.
|
|
66
|
-
* @param {object} data payload PostToolUse
|
|
67
|
-
* @param {string} cwd directorio del proyecto
|
|
68
|
-
* @param {Function} [registrar] inyectable para tests; default carga skill-metrics
|
|
69
|
-
* @returns {boolean} true si registró
|
|
70
|
-
*/
|
|
71
|
-
function procesar(data, cwd, registrar) {
|
|
72
|
-
const evento = extraerEvento(data);
|
|
73
|
-
if (!evento) return false;
|
|
74
|
-
const fn = registrar || cargarRegistrar();
|
|
75
|
-
if (!fn) return false;
|
|
76
|
-
fn(cwd, evento.skillName, evento.estado, 0);
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
module.exports = { extraerEvento, procesar };
|
|
81
|
-
|
|
82
|
-
// --- Entrypoint -------------------------------------------------------------
|
|
83
|
-
// Claude Code invoca el hook vía `node -e "require('./hooks/...')"`, donde
|
|
84
|
-
// `require.main` es undefined. Adjuntar stdin SOLO en ese caso (o invocación
|
|
85
|
-
// directa), nunca cuando un test requiere el módulo (ahí require.main es el
|
|
86
|
-
// runner, definido y ≠ este módulo) — así los tests no cuelgan en stdin.
|
|
87
|
-
if (!require.main || require.main === module) {
|
|
88
|
-
// Opt-out: no adjuntar el listener (sin process.exit, seguro de requerir).
|
|
89
|
-
if (process.env.SWL_SKILL_TELEMETRIA !== '0') {
|
|
90
|
-
let inputRaw = '';
|
|
91
|
-
process.stdin.on('data', (chunk) => { inputRaw += chunk; });
|
|
92
|
-
process.stdin.on('end', () => {
|
|
93
|
-
try {
|
|
94
|
-
procesar(JSON.parse(inputRaw), process.cwd());
|
|
95
|
-
} catch (_) {
|
|
96
|
-
// Silencioso — nunca interrumpir la sesión por un fallo de telemetría.
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook: telemetria-skill-routing.js
|
|
6
|
+
* Tipo: PostToolUse (matcher: "Skill")
|
|
7
|
+
*
|
|
8
|
+
* Cablea la lib huérfana `scripts/lib/skill-metrics.js`: por cada invocación
|
|
9
|
+
* del tool Skill registra la frecuencia/estado en `.planning/skill-metrics.json`
|
|
10
|
+
* vía `registrarUso(cwd, skillName, estado, duracionMs)`.
|
|
11
|
+
*
|
|
12
|
+
* Propósito (Revisión Evolutiva 04, P-2 "bloat y precisión de routing"):
|
|
13
|
+
* acumular telemetría de qué skills se invocan para alimentar la futura
|
|
14
|
+
* auditoría de bloat (skills muertos / solapados). Es la instrumentación que
|
|
15
|
+
* el roadmap permite adelantar como "tarea suelta" antes de la fase de auditoría.
|
|
16
|
+
*
|
|
17
|
+
* Distinto de telemetria-agentes.js (spans OTLP a traces/) y de audit-trail.js
|
|
18
|
+
* (todos los tool calls a audit.jsonl): este hook produce el agregado por-skill
|
|
19
|
+
* que la auditoría de bloat necesita y que ningún otro hook genera.
|
|
20
|
+
*
|
|
21
|
+
* NUNCA bloquea (siempre exit 0). Async: corre en background.
|
|
22
|
+
* Opt-out: SWL_SKILL_TELEMETRIA=0.
|
|
23
|
+
*
|
|
24
|
+
* Origen: punto P-2 de la Revisión Evolutiva 04 (instrumentación adelantada).
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extrae el evento de skill de un payload PostToolUse.
|
|
29
|
+
* Pura y testeable — no toca el filesystem.
|
|
30
|
+
*
|
|
31
|
+
* @param {object} data payload PostToolUse
|
|
32
|
+
* @returns {{skillName: string, estado: 'ok'|'error'}|null} null si no aplica
|
|
33
|
+
*/
|
|
34
|
+
function extraerEvento(data) {
|
|
35
|
+
if (!data || typeof data !== 'object') return null;
|
|
36
|
+
const toolName = String(data.tool_name || (data.tool && data.tool.name) || '');
|
|
37
|
+
if (toolName !== 'Skill') return null;
|
|
38
|
+
|
|
39
|
+
const input = data.tool_input || {};
|
|
40
|
+
const skillName = String(input.skill || input.name || '').trim();
|
|
41
|
+
if (!skillName) return null;
|
|
42
|
+
|
|
43
|
+
const esError = Boolean(data.error_message || data.error);
|
|
44
|
+
return { skillName, estado: esError ? 'error' : 'ok' };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Carga defensiva de la lib de métricas. Si no está disponible (destino
|
|
49
|
+
* aplanado, instalación parcial), retorna null y el hook degrada en silencio.
|
|
50
|
+
* @returns {Function|null} registrarUso o null
|
|
51
|
+
*/
|
|
52
|
+
function cargarRegistrar() {
|
|
53
|
+
try {
|
|
54
|
+
return require('../scripts/lib/skill-metrics').registrarUso;
|
|
55
|
+
} catch (_) {
|
|
56
|
+
try {
|
|
57
|
+
return require('./lib/skill-metrics').registrarUso;
|
|
58
|
+
} catch (_2) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Procesa un payload y registra el uso del skill si aplica.
|
|
66
|
+
* @param {object} data payload PostToolUse
|
|
67
|
+
* @param {string} cwd directorio del proyecto
|
|
68
|
+
* @param {Function} [registrar] inyectable para tests; default carga skill-metrics
|
|
69
|
+
* @returns {boolean} true si registró
|
|
70
|
+
*/
|
|
71
|
+
function procesar(data, cwd, registrar) {
|
|
72
|
+
const evento = extraerEvento(data);
|
|
73
|
+
if (!evento) return false;
|
|
74
|
+
const fn = registrar || cargarRegistrar();
|
|
75
|
+
if (!fn) return false;
|
|
76
|
+
fn(cwd, evento.skillName, evento.estado, 0);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { extraerEvento, procesar };
|
|
81
|
+
|
|
82
|
+
// --- Entrypoint -------------------------------------------------------------
|
|
83
|
+
// Claude Code invoca el hook vía `node -e "require('./hooks/...')"`, donde
|
|
84
|
+
// `require.main` es undefined. Adjuntar stdin SOLO en ese caso (o invocación
|
|
85
|
+
// directa), nunca cuando un test requiere el módulo (ahí require.main es el
|
|
86
|
+
// runner, definido y ≠ este módulo) — así los tests no cuelgan en stdin.
|
|
87
|
+
if (!require.main || require.main === module) {
|
|
88
|
+
// Opt-out: no adjuntar el listener (sin process.exit, seguro de requerir).
|
|
89
|
+
if (process.env.SWL_SKILL_TELEMETRIA !== '0') {
|
|
90
|
+
let inputRaw = '';
|
|
91
|
+
process.stdin.on('data', (chunk) => { inputRaw += chunk; });
|
|
92
|
+
process.stdin.on('end', () => {
|
|
93
|
+
try {
|
|
94
|
+
procesar(JSON.parse(inputRaw), process.cwd());
|
|
95
|
+
} catch (_) {
|
|
96
|
+
// Silencioso — nunca interrumpir la sesión por un fallo de telemetría.
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Hook: validar-formato-post-subagente.js
|
|
6
|
-
* Tipo: SubagentStop (async: true — fire-and-forget)
|
|
7
|
-
*
|
|
8
|
-
* Cuando un subagente SWL termina, valida que su output cumple con el
|
|
9
|
-
* schema declarado en `manifiestos/agent-output-schemas.json`. Si el
|
|
10
|
-
* agente no tiene schema declarado, el hook no hace nada — no asume
|
|
11
|
-
* que todo agente debe seguir el formato compacto.
|
|
12
|
-
*
|
|
13
|
-
* Registra el resultado en `.planning/evolution/formato-violaciones.jsonl`
|
|
14
|
-
* para que `metricas-evolucion.js` calcule la tasa de violación por
|
|
15
|
-
* agente y la incluya en el dashboard de calidad conductual.
|
|
16
|
-
*
|
|
17
|
-
* Schema simple: lista de patrones regex que DEBEN aparecer en el output.
|
|
18
|
-
* Si todos matchean → conforme. Si falta alguno → violación con detalle.
|
|
19
|
-
*
|
|
20
|
-
* Opt-out: SWL_FORMATO_VALIDACION=0 desactiva el hook.
|
|
21
|
-
*
|
|
22
|
-
* El hook nunca bloquea — solo registra para análisis posterior.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
const fs = require('fs');
|
|
26
|
-
const path = require('path');
|
|
27
|
-
|
|
28
|
-
const CWD = process.cwd();
|
|
29
|
-
const SCHEMAS_PATH = path.join(CWD, 'manifiestos', 'agent-output-schemas.json');
|
|
30
|
-
const LOG_PATH = path.join(CWD, '.planning', 'evolution', 'formato-violaciones.jsonl');
|
|
31
|
-
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
// Carga del schema (una vez)
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
|
|
36
|
-
function cargarSchemas() {
|
|
37
|
-
try {
|
|
38
|
-
const raw = fs.readFileSync(SCHEMAS_PATH, 'utf8');
|
|
39
|
-
const parsed = JSON.parse(raw);
|
|
40
|
-
return parsed.schemas || {};
|
|
41
|
-
} catch {
|
|
42
|
-
return {};
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
// Validación
|
|
48
|
-
// ---------------------------------------------------------------------------
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Compara el output contra el schema. Devuelve { violation, errors }.
|
|
52
|
-
* @param {string} output - Texto del output del subagente
|
|
53
|
-
* @param {object} schema - { patronesRequeridos: string[] }
|
|
54
|
-
*/
|
|
55
|
-
function validarOutput(output, schema) {
|
|
56
|
-
const errors = [];
|
|
57
|
-
const patrones = Array.isArray(schema.patronesRequeridos)
|
|
58
|
-
? schema.patronesRequeridos
|
|
59
|
-
: [];
|
|
60
|
-
for (const patron of patrones) {
|
|
61
|
-
// El schema puede declarar inline flags estilo (?im) por compatibilidad
|
|
62
|
-
// con regex POSIX. JavaScript no los soporta inline — los stripeamos
|
|
63
|
-
// y aplicamos 'im' siempre (case-insensitive + multiline).
|
|
64
|
-
const limpio = patron.replace(/^\(\?[imsxu]+\)/, '');
|
|
65
|
-
let regex;
|
|
66
|
-
try { regex = new RegExp(limpio, 'im'); }
|
|
67
|
-
catch { errors.push(`Patrón inválido en schema: ${patron}`); continue; }
|
|
68
|
-
if (!regex.test(output)) {
|
|
69
|
-
errors.push(`Falta patrón requerido: ${patron}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return { violation: errors.length > 0, errors };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Extrae el output textual del subagente del payload del hook.
|
|
77
|
-
* El payload del SubagentStop expone el resultado en distintos lugares
|
|
78
|
-
* según versión de Claude Code; intentamos varias rutas.
|
|
79
|
-
*/
|
|
80
|
-
function extraerOutput(data) {
|
|
81
|
-
const r = data.tool_response || data.tool_result || data.response || {};
|
|
82
|
-
// Posibles ubicaciones del output del subagente
|
|
83
|
-
if (typeof r.text === 'string') return r.text;
|
|
84
|
-
if (typeof r.content === 'string') return r.content;
|
|
85
|
-
if (Array.isArray(r.messages)) {
|
|
86
|
-
return r.messages
|
|
87
|
-
.map(m => (typeof m.content === 'string' ? m.content : ''))
|
|
88
|
-
.filter(Boolean)
|
|
89
|
-
.join('\n');
|
|
90
|
-
}
|
|
91
|
-
if (typeof r.output === 'string') return r.output;
|
|
92
|
-
return '';
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function ensureDir() {
|
|
96
|
-
try { fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true }); } catch { /* ignore */ }
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
// Entrypoint
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
|
|
103
|
-
let inputRaw = '';
|
|
104
|
-
process.stdin.on('data', chunk => { inputRaw += chunk; });
|
|
105
|
-
|
|
106
|
-
process.stdin.on('end', () => {
|
|
107
|
-
try {
|
|
108
|
-
if (process.env.SWL_FORMATO_VALIDACION === '0') return;
|
|
109
|
-
|
|
110
|
-
const data = JSON.parse(inputRaw);
|
|
111
|
-
const subagentType =
|
|
112
|
-
data.tool_input?.subagent_type ||
|
|
113
|
-
data.tool?.input?.subagent_type ||
|
|
114
|
-
data.subagent_type ||
|
|
115
|
-
null;
|
|
116
|
-
if (!subagentType) return;
|
|
117
|
-
|
|
118
|
-
const schemas = cargarSchemas();
|
|
119
|
-
const schema = schemas[subagentType];
|
|
120
|
-
if (!schema) return; // agente sin schema → no se evalúa
|
|
121
|
-
|
|
122
|
-
const output = extraerOutput(data);
|
|
123
|
-
if (!output || output.length < 10) return; // output trivial — no evaluar
|
|
124
|
-
|
|
125
|
-
const { violation, errors } = validarOutput(output, schema);
|
|
126
|
-
const entry = {
|
|
127
|
-
ts: new Date().toISOString(),
|
|
128
|
-
sessionId: String(data.session_id || 'default'),
|
|
129
|
-
agente: subagentType,
|
|
130
|
-
violation,
|
|
131
|
-
errors,
|
|
132
|
-
outputLen: output.length,
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
ensureDir();
|
|
136
|
-
fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + '\n', 'utf8');
|
|
137
|
-
} catch {
|
|
138
|
-
// SubagentStop hook nunca bloquea por error interno.
|
|
139
|
-
}
|
|
140
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook: validar-formato-post-subagente.js
|
|
6
|
+
* Tipo: SubagentStop (async: true — fire-and-forget)
|
|
7
|
+
*
|
|
8
|
+
* Cuando un subagente SWL termina, valida que su output cumple con el
|
|
9
|
+
* schema declarado en `manifiestos/agent-output-schemas.json`. Si el
|
|
10
|
+
* agente no tiene schema declarado, el hook no hace nada — no asume
|
|
11
|
+
* que todo agente debe seguir el formato compacto.
|
|
12
|
+
*
|
|
13
|
+
* Registra el resultado en `.planning/evolution/formato-violaciones.jsonl`
|
|
14
|
+
* para que `metricas-evolucion.js` calcule la tasa de violación por
|
|
15
|
+
* agente y la incluya en el dashboard de calidad conductual.
|
|
16
|
+
*
|
|
17
|
+
* Schema simple: lista de patrones regex que DEBEN aparecer en el output.
|
|
18
|
+
* Si todos matchean → conforme. Si falta alguno → violación con detalle.
|
|
19
|
+
*
|
|
20
|
+
* Opt-out: SWL_FORMATO_VALIDACION=0 desactiva el hook.
|
|
21
|
+
*
|
|
22
|
+
* El hook nunca bloquea — solo registra para análisis posterior.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
const path = require('path');
|
|
27
|
+
|
|
28
|
+
const CWD = process.cwd();
|
|
29
|
+
const SCHEMAS_PATH = path.join(CWD, 'manifiestos', 'agent-output-schemas.json');
|
|
30
|
+
const LOG_PATH = path.join(CWD, '.planning', 'evolution', 'formato-violaciones.jsonl');
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Carga del schema (una vez)
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
function cargarSchemas() {
|
|
37
|
+
try {
|
|
38
|
+
const raw = fs.readFileSync(SCHEMAS_PATH, 'utf8');
|
|
39
|
+
const parsed = JSON.parse(raw);
|
|
40
|
+
return parsed.schemas || {};
|
|
41
|
+
} catch {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Validación
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Compara el output contra el schema. Devuelve { violation, errors }.
|
|
52
|
+
* @param {string} output - Texto del output del subagente
|
|
53
|
+
* @param {object} schema - { patronesRequeridos: string[] }
|
|
54
|
+
*/
|
|
55
|
+
function validarOutput(output, schema) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
const patrones = Array.isArray(schema.patronesRequeridos)
|
|
58
|
+
? schema.patronesRequeridos
|
|
59
|
+
: [];
|
|
60
|
+
for (const patron of patrones) {
|
|
61
|
+
// El schema puede declarar inline flags estilo (?im) por compatibilidad
|
|
62
|
+
// con regex POSIX. JavaScript no los soporta inline — los stripeamos
|
|
63
|
+
// y aplicamos 'im' siempre (case-insensitive + multiline).
|
|
64
|
+
const limpio = patron.replace(/^\(\?[imsxu]+\)/, '');
|
|
65
|
+
let regex;
|
|
66
|
+
try { regex = new RegExp(limpio, 'im'); }
|
|
67
|
+
catch { errors.push(`Patrón inválido en schema: ${patron}`); continue; }
|
|
68
|
+
if (!regex.test(output)) {
|
|
69
|
+
errors.push(`Falta patrón requerido: ${patron}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { violation: errors.length > 0, errors };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Extrae el output textual del subagente del payload del hook.
|
|
77
|
+
* El payload del SubagentStop expone el resultado en distintos lugares
|
|
78
|
+
* según versión de Claude Code; intentamos varias rutas.
|
|
79
|
+
*/
|
|
80
|
+
function extraerOutput(data) {
|
|
81
|
+
const r = data.tool_response || data.tool_result || data.response || {};
|
|
82
|
+
// Posibles ubicaciones del output del subagente
|
|
83
|
+
if (typeof r.text === 'string') return r.text;
|
|
84
|
+
if (typeof r.content === 'string') return r.content;
|
|
85
|
+
if (Array.isArray(r.messages)) {
|
|
86
|
+
return r.messages
|
|
87
|
+
.map(m => (typeof m.content === 'string' ? m.content : ''))
|
|
88
|
+
.filter(Boolean)
|
|
89
|
+
.join('\n');
|
|
90
|
+
}
|
|
91
|
+
if (typeof r.output === 'string') return r.output;
|
|
92
|
+
return '';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function ensureDir() {
|
|
96
|
+
try { fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true }); } catch { /* ignore */ }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Entrypoint
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
let inputRaw = '';
|
|
104
|
+
process.stdin.on('data', chunk => { inputRaw += chunk; });
|
|
105
|
+
|
|
106
|
+
process.stdin.on('end', () => {
|
|
107
|
+
try {
|
|
108
|
+
if (process.env.SWL_FORMATO_VALIDACION === '0') return;
|
|
109
|
+
|
|
110
|
+
const data = JSON.parse(inputRaw);
|
|
111
|
+
const subagentType =
|
|
112
|
+
data.tool_input?.subagent_type ||
|
|
113
|
+
data.tool?.input?.subagent_type ||
|
|
114
|
+
data.subagent_type ||
|
|
115
|
+
null;
|
|
116
|
+
if (!subagentType) return;
|
|
117
|
+
|
|
118
|
+
const schemas = cargarSchemas();
|
|
119
|
+
const schema = schemas[subagentType];
|
|
120
|
+
if (!schema) return; // agente sin schema → no se evalúa
|
|
121
|
+
|
|
122
|
+
const output = extraerOutput(data);
|
|
123
|
+
if (!output || output.length < 10) return; // output trivial — no evaluar
|
|
124
|
+
|
|
125
|
+
const { violation, errors } = validarOutput(output, schema);
|
|
126
|
+
const entry = {
|
|
127
|
+
ts: new Date().toISOString(),
|
|
128
|
+
sessionId: String(data.session_id || 'default'),
|
|
129
|
+
agente: subagentType,
|
|
130
|
+
violation,
|
|
131
|
+
errors,
|
|
132
|
+
outputLen: output.length,
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
ensureDir();
|
|
136
|
+
fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + '\n', 'utf8');
|
|
137
|
+
} catch {
|
|
138
|
+
// SubagentStop hook nunca bloquea por error interno.
|
|
139
|
+
}
|
|
140
|
+
});
|