@saulwade/swl-ses 1.8.0 → 2.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.
Files changed (135) hide show
  1. package/CLAUDE.md +8 -8
  2. package/README.md +13 -13
  3. package/agentes/accesibilidad-wcag-swl.md +3 -3
  4. package/agentes/auto-evolucion-swl.md +908 -908
  5. package/agentes/disenador-ui-swl.md +6 -5
  6. package/agentes/frontend-angular-swl.md +2 -2
  7. package/agentes/frontend-css-swl.md +2 -2
  8. package/agentes/frontend-react-swl.md +4 -4
  9. package/agentes/frontend-swl.md +6 -6
  10. package/agentes/investigador-ux-swl.md +5 -5
  11. package/agentes/orquestador-swl.md +96 -8
  12. package/agentes/perfilador-usuario-swl.md +308 -308
  13. package/agentes/producto-prd-swl.md +1 -1
  14. package/agentes/red-team-swl.md +218 -218
  15. package/agentes/revisor-codigo-swl.md +34 -10
  16. package/agentes/revisor-seguridad-swl.md +7 -0
  17. package/agentes/tdd-qa-swl.md +39 -2
  18. package/comandos/swl/actualizar.md +1 -1
  19. package/comandos/swl/aprender.md +2 -2
  20. package/comandos/swl/aprobar-plan.md +152 -0
  21. package/comandos/swl/autoresearch.md +102 -6
  22. package/comandos/swl/ayuda.md +3 -3
  23. package/comandos/swl/discutir-fase.md +20 -2
  24. package/comandos/swl/ejecutar-fase.md +53 -6
  25. package/comandos/swl/evolucionar.md +1 -1
  26. package/comandos/swl/inbox.md +1 -1
  27. package/comandos/swl/instalar.md +1 -1
  28. package/comandos/swl/nemesis.md +42 -1
  29. package/comandos/swl/planear-fase.md +25 -1
  30. package/comandos/swl/plugins.md +1 -1
  31. package/comandos/swl/predecir.md +139 -0
  32. package/comandos/swl/release.md +1 -1
  33. package/comandos/swl/status.md +279 -0
  34. package/comandos/swl/verificar.md +75 -7
  35. package/habilidades/ai-runtime-security/SKILL.md +1 -1
  36. package/habilidades/angular-moderno/SKILL.md +44 -1
  37. package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -276
  38. package/habilidades/autoresearch/SKILL.md +15 -1
  39. package/habilidades/benchmark-memoria/SKILL.md +1 -1
  40. package/habilidades/calidad-contract-testing/SKILL.md +165 -0
  41. package/habilidades/calidad-mutation-testing/SKILL.md +170 -0
  42. package/habilidades/changelog-generator/SKILL.md +9 -2
  43. package/habilidades/changelog-generator/scripts/parse-commits.js +12 -1
  44. package/habilidades/checklist-seguridad/SKILL.md +29 -1
  45. package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -0
  46. package/habilidades/css-moderno/SKILL.md +3 -1
  47. package/habilidades/diagrama-arquitectura/SKILL.md +1 -1
  48. package/habilidades/drift-detection/SKILL.md +179 -179
  49. package/habilidades/ejecutar-fase/SKILL.md +64 -14
  50. package/habilidades/estructura-proyecto-claude/SKILL.md +17 -14
  51. package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +34 -23
  52. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +70 -53
  53. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -77
  54. package/habilidades/extractor-de-aprendizajes/SKILL.md +9 -5
  55. package/habilidades/fastapi-experto/SKILL.md +56 -5
  56. package/habilidades/harness-claude-code/SKILL.md +10 -7
  57. package/{reglas/harness-claude-code.md → habilidades/harness-claude-code/recursos/disciplina-harness-regla.md} +2 -2
  58. package/habilidades/instalar-sistema/SKILL.md +3 -3
  59. package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +1 -1
  60. package/habilidades/patrones-python/SKILL.md +8 -5
  61. package/habilidades/perfil-usuario/SKILL.md +200 -200
  62. package/habilidades/planear-fase/SKILL.md +25 -4
  63. package/habilidades/proceso-ddia-fundamentos/SKILL.md +1 -1
  64. package/habilidades/proceso-ddia-streaming/SKILL.md +4 -4
  65. package/habilidades/proceso-debate-adversarial/SKILL.md +164 -0
  66. package/habilidades/proceso-debate-adversarial/recursos/personas.md +105 -0
  67. package/habilidades/proceso-dynamic-workflows/SKILL.md +138 -0
  68. package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -0
  69. package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -0
  70. package/habilidades/protocolo-revision-swl/SKILL.md +1 -1
  71. package/habilidades/seguridad-skills-ia/SKILL.md +1 -1
  72. package/habilidades/swl-claudemd/SKILL.md +50 -210
  73. package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -0
  74. package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -0
  75. package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -0
  76. package/habilidades/swl-dashboard/SKILL.md +9 -9
  77. package/habilidades/swl-revisar-impacto/SKILL.md +1 -1
  78. package/habilidades/tdd-workflow/SKILL.md +58 -5
  79. package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -0
  80. package/habilidades/validacion-ci-sistema/SKILL.md +3 -3
  81. package/hooks/calidad-pre-commit.js +340 -3
  82. package/hooks/ciclo-evolucion-subagente.js +26 -0
  83. package/hooks/ciclo-evolucion.js +26 -0
  84. package/hooks/contexto-iteracion.js +144 -0
  85. package/hooks/extraccion-aprendizajes.js +13 -0
  86. package/hooks/lib/ciclo-evolucion.js +47 -0
  87. package/hooks/{auto-evolucion.js → lib/etapa-auto-evolucion.js} +701 -700
  88. package/hooks/{metricas-evolucion.js → lib/etapa-metricas.js} +388 -376
  89. package/hooks/{actualizar-perfil-usuario.js → lib/etapa-perfil-usuario.js} +376 -364
  90. package/hooks/lib/evolution-tracker.js +24 -3
  91. package/hooks/lib/loop-telemetry.js +321 -0
  92. package/hooks/notificacion-telegram.js +11 -3
  93. package/hooks/spec-gate.js +211 -0
  94. package/hooks/tdd-gate.js +241 -0
  95. package/hooks/validar-intent-spec.js +30 -10
  96. package/llms.txt +29 -0
  97. package/manifiestos/hooks-config.json +36 -18
  98. package/manifiestos/modulos.json +23 -14
  99. package/manifiestos/skills-lock.json +100 -72
  100. package/package.json +4 -3
  101. package/plugin.json +9 -10
  102. package/reglas/accesibilidad.md +10 -0
  103. package/reglas/api-diseno.md +9 -0
  104. package/reglas/arquitectura.evolved.json +7 -0
  105. package/reglas/arquitectura.md +65 -0
  106. package/reglas/auditorias-documentales-estructurales.md +7 -0
  107. package/reglas/cloud-infra.md +8 -0
  108. package/reglas/fragmentos-compartidos.md +5 -0
  109. package/reglas/gobernanza.md +4 -4
  110. package/reglas/hooks.md +6 -0
  111. package/reglas/intent-engineering.md +4 -0
  112. package/reglas/markitdown.md +8 -0
  113. package/reglas/memoria-consolidada.md +1 -1
  114. package/reglas/patrones.md +6 -0
  115. package/reglas/registro-componentes-nuevos.md +10 -1
  116. package/reglas/seguridad-agentes.md +1 -1
  117. package/reglas/seguridad.evolved.json +7 -0
  118. package/reglas/seguridad.md +144 -0
  119. package/reglas/skills-estandar.md +6 -0
  120. package/reglas/testing.md +7 -0
  121. package/reglas/tests-cleanup.md +4 -0
  122. package/reglas/usar-sistema-swl.md +1 -1
  123. package/scripts/generar-inventario.js +64 -1
  124. package/scripts/instalador.js +32 -2
  125. package/scripts/lib/gitignore-manifest.js +29 -1
  126. package/scripts/lib/plan-lock.js +275 -0
  127. package/scripts/migrar-fase-dominio.js +0 -1
  128. package/scripts/smoke-test.js +24 -2
  129. package/scripts/verificar-trazabilidad.js +292 -0
  130. package/agentes/ux-disenador-swl.md +0 -503
  131. package/comandos/swl/dashboard.md +0 -146
  132. package/comandos/swl/evolucion-estado.md +0 -191
  133. package/comandos/swl/metricas.md +0 -342
  134. package/comandos/swl/salud.md +0 -481
  135. package/reglas/verificar-citas-temporales.md +0 -139
@@ -1,191 +0,0 @@
1
- ---
2
- name: swl:evolucion-estado
3
- description: Dashboard del ciclo de auto-evolución del sistema SWL. Muestra health_score compuesto, tasa de acción de nudges, densidad de instintos, fallos de agentes, evoluciones aplicadas/revertidas y alertas persistentes. Responde en una pantalla a "¿SWL está aprendiendo esta semana?".
4
- argument-hint: [--json | --dias=N | --regenerar]
5
- allowed_tools: ["Read", "Bash"]
6
- user-invocable: true
7
- version: "1.0.0"
8
- ---
9
-
10
- # /swl:evolucion-estado — Dashboard del ciclo de evolución
11
-
12
- Emite un reporte compacto del estado de auto-evolución del sistema SWL en la
13
- ventana reciente (default 14 días). Su propósito: responder a la pregunta
14
- **"¿el sistema está aprendiendo?"** con datos, no impresiones.
15
-
16
- ## Flags
17
-
18
- - `--json` → emite el JSON crudo de `metricas.json` (útil para pipes).
19
- - `--dias=N` → regenera métricas con ventana de N días (default 14).
20
- - `--regenerar` → fuerza recomputo ejecutando el hook `metricas-evolucion.js`.
21
- Útil cuando no se ha disparado Stop recientemente.
22
-
23
- ## Paso 0 — Asegurar métricas frescas
24
-
25
- Si se pasó `--regenerar` o `metricas.json` tiene > 24h:
26
-
27
- ```bash
28
- PATH="/c/Program Files/nodejs:/c/Program Files (x86)/nodejs:$PATH" echo '{}' | node hooks/metricas-evolucion.js
29
- ```
30
-
31
- ## Paso 1 — Cargar métricas
32
-
33
- ```bash
34
- cat .planning/evolution/metricas.json
35
- ```
36
-
37
- Si el archivo no existe: ejecutar el regenerado del Paso 0. Si sigue sin
38
- existir: reportar "el ciclo de evolución no ha corrido aún; ejecuta cualquier
39
- tarea para poblar métricas iniciales".
40
-
41
- ## Paso 1.5 — Cargar contexto del kernel (gobernanza)
42
-
43
- Para el bloque **KERNEL** del dashboard, recolectar:
44
-
45
- ```bash
46
- # 1. Conteo de agentes evolvable=false vs total
47
- TOTAL=$(ls agentes/*.md | grep -v "^agentes/_" | wc -l)
48
- EVOL_FALSE=$(grep -l '^evolvable: false' agentes/*.md | wc -l)
49
-
50
- # 2. Último ADR del repo madre — el más reciente por fecha en frontmatter
51
- ULTIMO_ADR=$(ls .planning/adrs/[0-9]*.md | sort -r | head -1)
52
- TITULO=$(head -1 "$ULTIMO_ADR" | sed 's/^# //')
53
- FECHA=$(grep -m1 '^\*\*Fecha\*\*:' "$ULTIMO_ADR" | sed 's/.*\*\*Fecha\*\*:\s*//')
54
-
55
- echo "ADR_KERNEL_LINEA=\"$TITULO — $FECHA\""
56
- echo "RATIO=\"$EVOL_FALSE/$TOTAL\""
57
- ```
58
-
59
- Estos valores alimentan la sección KERNEL del template.
60
-
61
- Si `.planning/evolution/politica-evolvable.md` no existe, reportar como
62
- hallazgo crítico: el kernel SIN política documentada es violación de
63
- `reglas/gobernanza.md`.
64
-
65
- ## Paso 2 — Emitir el dashboard (formato humano)
66
-
67
- Template de salida:
68
-
69
- ```
70
- ═══════════════════════════════════════════════════════════════
71
- SWL — Estado del ciclo de evolución
72
- Ventana: últimos N días · Generado: <ts>
73
- ═══════════════════════════════════════════════════════════════
74
-
75
- Health score: <N>/100 <badge>
76
-
77
- NUDGES
78
- Emitidos .............. <total>
79
- Accionados ............ <n> (<tasa>%)
80
- Pendientes ............ <n>
81
- Por tipo:
82
- perfil-usuario <a>/<t> (<%>)
83
- auto-evolucion <a>/<t> (<%>)
84
- consolidacion <a>/<t> (<%>)
85
-
86
- INSTINTOS
87
- Proyecto .............. <n>
88
- Global ................ <n>
89
- Perfil-usuario ........ <n>
90
- Aprendizajes totales .. <n>
91
-
92
- AGENTES (14d)
93
- Runs totales .......... <n>
94
- Fallos ................ <n>
95
- Tasa de éxito ......... <%>
96
-
97
- EVOLUCIONES (30d)
98
- Aplicadas ............. <n>
99
- Revertidas ............ <n>
100
- Neta .................. <n>
101
- Rollback ratio ........ <%> (N/A si aplicadas == 0)
102
-
103
- CALIDAD CONDUCTUAL (14d)
104
- Fallos por tipo:
105
- bad_output_format <n>
106
- tool_error <n>
107
- timeout <n>
108
- schema_violation <n>
109
- task_incomplete <n>
110
- unknown <n>
111
- Reintentos consecutivos
112
- Total ............... <n> (mismo agente, misma task, ≤30 min)
113
- Top agente .......... <agente>: <n>
114
- Latencia top agente
115
- Mediana ............. <ms>
116
- p95 ................. <ms>
117
- Sin instrumentación todavía:
118
- • precision_routing_fase_dominio
119
- • utilidad_memoria_recuperada
120
- • violaciones_formato_post_ejecucion
121
-
122
- ALERTAS PERSISTENTES
123
- <si alertasActivas.length === 0>
124
- Sin alertas.
125
- <sino>
126
- [!] kind=X target=Y count=Z (primera: fecha)
127
- ...
128
-
129
- KERNEL (gobernanza)
130
- Política evolvable .... .planning/evolution/politica-evolvable.md
131
- Último ADR kernel ..... <ADR-NNNN — título — fecha>
132
- Agentes evolvable=false <n>/<total>
133
-
134
- ═══════════════════════════════════════════════════════════════
135
- ```
136
-
137
- ## Paso 3 — Calcular badge del health_score
138
-
139
- | Rango | Badge | Interpretación |
140
- |-------|-------|----------------|
141
- | ≥ 90 | 🏆 Óptimo | ciclo completo, cerrado y saludable |
142
- | ≥ 75 | 🥇 Saludable | funcionando con pequeñas mejoras pendientes |
143
- | ≥ 60 | 🥈 Parcial | hay piezas sin activar; revisar recomendaciones |
144
- | ≥ 40 | 🥉 Esqueleto | infraestructura existe pero poco uso real |
145
- | < 40 | ⚠️ Dormido | el ciclo no está corriendo |
146
-
147
- ## Paso 4 — Recomendaciones contextuales
148
-
149
- Al final del dashboard, sugerir acciones según las métricas:
150
-
151
- - Si `instintos.proyecto === 0` y `aprendizajes_totales > 10`:
152
- → `npx -y @saulwade/swl-ses@latest bootstrap-instincts` (pobla desde APRENDIZAJES.md)
153
-
154
- - Si `nudges.tasaAccion < 0.3` y `nudges.total > 5`:
155
- → "Muchos nudges ignorados. Revisa `.planning/evolution/alertas-persistentes.json`"
156
-
157
- - Si `alertasActivas.length > 0`:
158
- → listar cada alerta con `/swl:evolucionar <target>` o cmd correspondiente
159
-
160
- - Si `agentes.tasaExito < 70` y `totalRuns > 5`:
161
- → "Agentes con tasa de éxito baja. Candidatos a `/swl:evolucionar`:
162
- <top 3 de porAgente con más fallos>"
163
-
164
- - Si `evoluciones.revertidas > evoluciones.aplicadas / 2`:
165
- → "Muchas evoluciones revertidas — revisar si el gate de regresión
166
- está siendo demasiado laxo o si los evals son inconsistentes"
167
-
168
- - Si `health_score >= 90`:
169
- → "Sistema en óptimo. Posible candidato a habilitar modo autónomo
170
- de `auto-evolucion-swl`. Ver `agentes/auto-evolucion-swl.md` —
171
- sección 'Autonomía condicional'"
172
-
173
- - Si `health_score < 95`:
174
- → "Para subir el score, consultar `.planning/ROADMAP-EVOLUCION.md` —
175
- documenta los 5 hitos por fase y cuánto aporta cada uno. Sin uso
176
- operacional real (nudges accionados, runs reales, evoluciones), el
177
- score no sube por infraestructura sola."
178
-
179
- ## Anti-substitution guardrails
180
-
181
- - Archivo de métricas: **siempre** `.planning/evolution/metricas.json` (nunca `.planning/metricas.json`, `evolucion.json`, `estado-evolucion.json`).
182
- - Hook que regenera: **siempre** `hooks/metricas-evolucion.js` (nunca `metrics.js`, `evolucion-metricas.js`, `evolution-metrics.js`).
183
- - Para forzar regen: pipe `echo '{}' | node ...`, nunca invocar `require()` directo.
184
-
185
- ## Response Discipline
186
-
187
- Si el usuario pasa `--json`: respuesta = **contenido crudo del archivo**,
188
- sin prosa ni comentarios.
189
-
190
- Si no: dashboard formateado con las 5 secciones. Las recomendaciones del
191
- Paso 4 van al final, máximo 3 items priorizados. Sin repetir datos del dashboard.
@@ -1,342 +0,0 @@
1
- ---
2
- name: swl:metricas
3
- description: Muestra métricas acumuladas de la sesión de trabajo actual: tokens consumidos, costo estimado en USD, tool calls y distribución por herramienta. Cargar cuando el usuario quiera ver el consumo de la sesión, verificar el presupuesto o entender qué herramientas dominan el costo.
4
- allowed_tools: ["Read", "Write", "Bash", "Glob", "Grep"]
5
- ---
6
-
7
- # /swl:metricas — Métricas de la sesión actual
8
-
9
- Muestra las métricas acumuladas de la sesión de trabajo actual: tokens,
10
- costo estimado, herramientas más usadas y estado del presupuesto configurado.
11
-
12
- ## Cuándo usar
13
-
14
- - Para saber cuánto se ha consumido en la sesión antes de continuar
15
- - Para identificar qué operaciones generan más costo
16
- - Para verificar si se está cerca del límite de presupuesto
17
- - Al final de una sesión para registrar el consumo real
18
-
19
- ## Subcomandos
20
-
21
- ```
22
- /swl:metricas — Resumen de métricas de la sesión
23
- /swl:metricas detalle — Desglose completo por herramienta y timeline
24
- /swl:metricas fases — Progreso de fases del proyecto desde feature-list.json
25
- /swl:metricas historico — Abre el dashboard histórico multi-sesión (alias de /swl:dashboard)
26
- ```
27
-
28
- ---
29
-
30
- ## Paso 1 — Leer fuentes de datos disponibles
31
-
32
- ### Fuente 1: archivo de métricas de sesión
33
-
34
- ```bash
35
- # Bridge de tracking generado por el hook de costos
36
- ls /tmp/swl-costs-*.json 2>/dev/null | sort -t- -k3 -n | tail -1
37
- ```
38
-
39
- Si existe, leerlo. Contiene el acumulado de tool calls, tokens y costos de la sesión.
40
-
41
- ### Fuente 2: métricas persistidas del proyecto
42
-
43
- ```bash
44
- cat .planning/METRICAS.md 2>/dev/null || echo "(sin métricas previas guardadas)"
45
- ```
46
-
47
- ### Fuente 3: configuración de presupuesto
48
-
49
- ```bash
50
- cat manifiestos/hooks-config.json | python3 -c "
51
- import json, sys
52
- cfg = json.load(sys.stdin)
53
- budget = cfg.get('costBudget', {})
54
- print('maxUsd:', budget.get('maxUsd', 'no configurado'))
55
- print('maxTokens:', budget.get('maxTokens', 'no configurado'))
56
- print('alertAt:', budget.get('alertAt', 'no configurado'))
57
- " 2>/dev/null || echo "(sin presupuesto configurado)"
58
- ```
59
-
60
- ---
61
-
62
- ## Paso 2 — Calcular y mostrar resumen
63
-
64
- Construir el resumen con los datos disponibles. Si no hay bridge activo,
65
- usar estimaciones basadas en el historial de `.planning/METRICAS.md`.
66
-
67
- ### Formato de resumen
68
-
69
- ```
70
- ╔══════════════════════════════════════════════════════╗
71
- ║ SWL — Métricas de Sesión ║
72
- ╚══════════════════════════════════════════════════════╝
73
-
74
- Sesión actual
75
- ─────────────────────────────────────────────────────
76
- Tool calls totales: NNN
77
- Tokens consumidos: ~NNN,NNN (entrada + salida)
78
- Costo estimado: ~$N.NNNN USD
79
- Modelo predominante: claude-sonnet / claude-opus
80
- Duración estimada: ~N minutos
81
-
82
- Presupuesto
83
- ─────────────────────────────────────────────────────
84
- Límite configurado: $N.NN USD / NNN,NNN tokens
85
- Consumido: NN% [████████░░] N.NN USD
86
- Estado: OK / ALERTA / EXCEDIDO
87
-
88
- Top 5 herramientas por costo
89
- ─────────────────────────────────────────────────────
90
- 1. Bash NNN calls ~$N.NNNN
91
- 2. Read NNN calls ~$N.NNNN
92
- 3. Write NNN calls ~$N.NNNN
93
- 4. Grep NNN calls ~$N.NNNN
94
- 5. Edit NNN calls ~$N.NNNN
95
- ```
96
-
97
- Si el estado es ALERTA (>= `alertAt` del presupuesto):
98
- indicar con mensaje visible y sugerir `/swl:compactar` para reducir contexto.
99
-
100
- Si el estado es EXCEDIDO:
101
- indicar claramente y recomendar revisar la configuración en `manifiestos/hooks-config.json`.
102
-
103
- ---
104
-
105
- ## Paso 3 (detalle) — Desglose completo
106
-
107
- Solo si se invocó `/swl:metricas detalle`:
108
-
109
- ### Tabla completa por herramienta
110
-
111
- ```
112
- Herramienta Calls Tokens entrada Tokens salida Costo USD
113
- ─────────────────────────────────────────────────────────────────────
114
- Bash NNN NNN,NNN NNN,NNN $N.NNNN
115
- Read NNN NNN,NNN NNN,NNN $N.NNNN
116
- Write NNN NNN,NNN NNN,NNN $N.NNNN
117
- Edit NNN NNN,NNN NNN,NNN $N.NNNN
118
- Grep NNN NNN,NNN NNN,NNN $N.NNNN
119
- Glob NNN NNN,NNN NNN,NNN $N.NNNN
120
- Agent NNN NNN,NNN NNN,NNN $N.NNNN
121
- Skill NNN NNN,NNN NNN,NNN $N.NNNN
122
- ─────────────────────────────────────────────────────────────────────
123
- TOTAL NNN NNN,NNN NNN,NNN $N.NNNN
124
- ```
125
-
126
- ### Comparativa histórica (si existe usage.db)
127
-
128
- Ejecutar el siguiente script Python para comparar la sesión actual contra el promedio
129
- histórico de los últimos 30 días almacenado en `~/.claude/usage.db`:
130
-
131
- ```bash
132
- python3 - << 'EOF'
133
- import sqlite3, json, os
134
- from pathlib import Path
135
- from datetime import datetime, timedelta, timezone
136
-
137
- db = Path.home() / ".claude" / "usage.db"
138
- if not db.exists():
139
- print("(sin base de datos histórica — ejecuta /swl:dashboard primero para generarla)")
140
- else:
141
- conn = sqlite3.connect(db)
142
- conn.row_factory = sqlite3.Row
143
- ahora = datetime.now(timezone.utc)
144
- hace30 = (ahora - timedelta(days=30)).isoformat()
145
- hoy = ahora.strftime("%Y-%m-%d")
146
-
147
- # Promedio de los últimos 30 días por sesión
148
- res = conn.execute("""
149
- SELECT COUNT(DISTINCT session_id) as sesiones,
150
- ROUND(AVG(input_tokens + output_tokens), 0) as avg_tokens_por_turno,
151
- SUM(input_tokens + output_tokens) as total_tokens
152
- FROM turns WHERE timestamp >= ?
153
- """, (hace30,)).fetchone()
154
-
155
- # Top 5 agentes SWL históricos
156
- try:
157
- agentes = conn.execute("""
158
- SELECT agent_name, COUNT(*) as n
159
- FROM turns
160
- WHERE agent_name IS NOT NULL AND timestamp >= ?
161
- GROUP BY agent_name ORDER BY n DESC LIMIT 5
162
- """, (hace30,)).fetchall()
163
- top_agentes = ", ".join(f"{r['agent_name']}({r['n']})" for r in agentes) or "(sin datos)"
164
- except Exception:
165
- top_agentes = "(columna agent_name no disponible — requiere nuevo scan)"
166
-
167
- # Top 5 skills SWL históricos
168
- try:
169
- skills = conn.execute("""
170
- SELECT skill_name, COUNT(*) as n
171
- FROM turns
172
- WHERE skill_name IS NOT NULL AND timestamp >= ?
173
- GROUP BY skill_name ORDER BY n DESC LIMIT 5
174
- """, (hace30,)).fetchall()
175
- top_skills = ", ".join(f"{r['skill_name']}({r['n']})" for r in skills) or "(sin datos)"
176
- except Exception:
177
- top_skills = "(columna skill_name no disponible — requiere nuevo scan)"
178
-
179
- conn.close()
180
- print(f"\nComparativa histórica (últimos 30 días)")
181
- print(f"{'─'*52}")
182
- print(f" Sesiones registradas: {res['sesiones'] or 0}")
183
- print(f" Total tokens: {(res['total_tokens'] or 0):,}")
184
- print(f" Avg tokens/turno: {int(res['avg_tokens_por_turno'] or 0):,}")
185
- print(f" Top agentes SWL: {top_agentes}")
186
- print(f" Top skills SWL: {top_skills}")
187
- print(f"\n Para ver gráficas completas: /swl:dashboard")
188
- EOF
189
- ```
190
-
191
- ### Desglose por agente SWL (sesión actual)
192
-
193
- Leer el bridge `/tmp/swl-costs-*.json` activo y extraer `costePorAgente`:
194
-
195
- ```bash
196
- python3 - << 'EOF'
197
- import json, glob, os
198
- bridges = sorted(glob.glob(os.path.join(os.environ.get('TMPDIR', '/tmp'), 'swl-costs-*.json')))
199
- if not bridges:
200
- print("(sin datos de agentes en esta sesión)")
201
- else:
202
- data = json.load(open(bridges[-1]))
203
- agentes = data.get('costePorAgente', {})
204
- if not agentes:
205
- print("(no se invocaron agentes SWL en esta sesión)")
206
- else:
207
- total_costo = data.get('costoTotal', 0)
208
- print(f"\nAgentes SWL — sesión actual")
209
- print("─" * 68)
210
- print(f" {'Agente':<35} {'Calls':>6} {'Tokens':>9} {'Costo':>8} {'%':>5}")
211
- print("─" * 68)
212
- for nombre, d in sorted(agentes.items(), key=lambda x: -x[1].get('costo', 0)):
213
- pct = f"{d['costo']/total_costo*100:.1f}%" if total_costo > 0 else "—"
214
- nombre_c = nombre[:35]
215
- print(f" {nombre_c:<35} {d.get('llamadas',0):>6} {d.get('tokens',0):>9,} ${d.get('costo',0):>7.4f} {pct:>5}")
216
- print("─" * 68)
217
- EOF
218
- ```
219
-
220
- ### Timeline de actividad
221
-
222
- Agrupar las tool calls por bloque de tiempo (5 minutos) y mostrar la distribución
223
- de actividad a lo largo de la sesión. Útil para identificar picos de consumo
224
- asociados a tareas específicas.
225
-
226
- ---
227
-
228
- ## Paso 4 — Persistir en METRICAS.md (opcional)
229
-
230
- Si el usuario lo solicita o si se detecta fin de sesión (via checkpoint):
231
-
232
- ```bash
233
- cat >> .planning/METRICAS.md << 'EOF'
234
-
235
- ## Sesión YYYY-MM-DD HH:MM
236
-
237
- - Tool calls: NNN
238
- - Tokens: ~NNN,NNN
239
- - Costo estimado: ~$N.NNNN USD
240
- - Modelo: claude-sonnet
241
- - Duración: ~N min
242
- - Comando que más consumió: Bash (NN%)
243
- EOF
244
- ```
245
-
246
- ---
247
-
248
- ---
249
-
250
- ## Subcomando: `fases` — Progreso de fases del proyecto
251
-
252
- Si el usuario invoca `/swl:metricas fases`, muestra el estado actual de las
253
- fases del proyecto leyendo el JSON derivado de `HOJA-RUTA.md`.
254
-
255
- ### Generación y lectura del estado
256
-
257
- ```bash
258
- # Regenerar el JSON desde HOJA-RUTA.md (fuente de verdad markdown)
259
- node scripts/derivar-feature-list.js
260
-
261
- # Leer el JSON generado en .planning/feature-list.json
262
- cat .planning/feature-list.json | python3 -c "
263
- import json, sys
264
- data = json.load(sys.stdin)
265
- t = data['totales']
266
- total = t['fases'] or 1
267
- pct = (t['completadas'] / total) * 100
268
-
269
- print(f\"\\nSWL — Progreso de fases del proyecto\")
270
- print('─' * 60)
271
- print(f\" Total de fases: {t['fases']}\")
272
- print(f\" Completadas: {t['completadas']} ({pct:.0f}%)\")
273
- print(f\" En progreso: {t['en_progreso']}\")
274
- print(f\" Pendientes: {t['pendientes']}\")
275
- print(f\" Bloqueadas: {t['bloqueadas']}\")
276
- print(f\" Spec lista: {t['spec_listas']}\")
277
- print('─' * 60)
278
- print()
279
- for f in data['fases']:
280
- estado = f['estado']
281
- marca = {'completado': '✓', 'en_progreso': '◐', 'pendiente': '○',
282
- 'bloqueado': '✗', 'spec_listo': '◔'}.get(estado, '?')
283
- nombre = f['nombre'][:48]
284
- art = f.get('artefactos') or {}
285
- plan = ' [PLAN]' if art.get('plan_md') else ''
286
- resumen = ' [RESUMEN]' if art.get('resumen_md') else ''
287
- print(f\" {marca} Fase {f['numero']:>2}: {nombre:<50}{plan}{resumen}\")
288
- print()
289
- print(f\" Fuente: {data['fuente']} · Generado: {data['generado_en']}\")
290
- "
291
- ```
292
-
293
- ### Lo que se reporta
294
-
295
- - **Totales**: cuántas fases hay y cuántas en cada estado canónico (`completado`,
296
- `en_progreso`, `pendiente`, `bloqueado`, `spec_listo`).
297
- - **Lista de fases** con marca visual de estado y artefactos presentes
298
- (`[PLAN]` si existe `0N-PLAN.md`, `[RESUMEN]` si existe `0N-RESUMEN.md`).
299
- - **Timestamp** de generación para detectar staleness.
300
-
301
- ### Cuándo usar
302
-
303
- - Antes de retomar trabajo en una fase, para ver el estado actualizado.
304
- - Al cerrar una sesión productiva, para verificar progreso vs HOJA-RUTA.md.
305
- - Para auditoría programática (consumir el JSON desde un hook o dashboard externo).
306
-
307
- ### Detección de drift
308
-
309
- Si `HOJA-RUTA.md` se modifica pero `feature-list.json` no se regenera, los datos
310
- quedan desactualizados. Para verificar:
311
-
312
- ```bash
313
- node scripts/derivar-feature-list.js --check
314
- # exit 0 = sincronizado, exit 2 = drift detectado
315
- ```
316
-
317
- `/swl:metricas fases` siempre regenera primero, así que ve estado fresco.
318
-
319
- ---
320
-
321
- ## Subcomando: `historico`
322
-
323
- Si el usuario invoca `/swl:metricas historico`, redirigir inmediatamente a:
324
-
325
- ```
326
- Invocar Skill("swl-dashboard") con subcomando "dashboard".
327
- ```
328
-
329
- Muestra el historial completo multi-sesión con gráficas interactivas en
330
- http://localhost:8080. Ver `/swl:dashboard` para más detalles.
331
-
332
- ---
333
-
334
- ## Notas de precisión
335
-
336
- Los costos son estimaciones basadas en los precios publicados de la API de Anthropic.
337
- El costo real puede variar según:
338
- - Modelo efectivamente usado (fallback a haiku en contextos de bajo riesgo)
339
- - Caché de prompt (reduce costo de tokens de entrada repetidos)
340
- - Variaciones de precio por región o plan
341
-
342
- Para costos exactos, consultar el dashboard de Anthropic Console.