swl-ses 3.3.2 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -1,4 +1,4 @@
1
- # CLAUDE.md — swl-software-engineering-system v3.0
1
+ # CLAUDE.md — swl-software-engineering-system v3.3
2
2
 
3
3
  Este archivo guía a Claude Code cuando trabaja en este repositorio.
4
4
 
@@ -174,7 +174,7 @@ backend-api-swl (diseño de API)
174
174
 
175
175
  Los miembros se lanzan en **paralelo real** (múltiples `Agent()` en un solo mensaje).
176
176
 
177
- ## Sistema de habilidades (61 en español + 40 en inglés)
177
+ ## Sistema de habilidades (62 en español + 40 en inglés)
178
178
 
179
179
  ### Estándar oficial de skills (regla: `skills-estandar.md`)
180
180
 
@@ -102,6 +102,7 @@
102
102
  "habilidades/aprendizaje-continuo",
103
103
  "habilidades/auto-evolucion-protocolo",
104
104
  "habilidades/checklist-calidad",
105
+ "habilidades/tdd-workflow",
105
106
  "habilidades/checkpoints-verificacion",
106
107
  "habilidades/validacion-ci-sistema",
107
108
  "habilidades/estructura-proyecto-claude",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "swl-ses",
3
- "version": "3.3.2",
4
- "description": "Sistema de ingenieria de software auto-evolutivo con 37 agentes, 61 habilidades, 16 comandos, 11 reglas y 6 hooks. Cubre el SDLC completo. 100% en espanol (Mexico).",
3
+ "version": "3.3.4",
4
+ "description": "Sistema de ingenieria de software auto-evolutivo con 37 agentes, 62 habilidades, 17 comandos, 11 reglas y 6 hooks. Cubre el SDLC completo. 100% en espanol (Mexico).",
5
5
  "bin": {
6
6
  "swl-ses": "bin/swl-ses.js"
7
7
  },
@@ -56,13 +56,16 @@ function escribirSettings(settingsPath, settings) {
56
56
 
57
57
  /**
58
58
  * Determina si un hook entry en settings.json pertenece a SWL.
59
- * @param {object} entry - { matcher, command }
59
+ * @param {object} entry - { matcher, hooks: [{ type, command }] }
60
60
  * @returns {boolean}
61
61
  */
62
62
  function esHookSWL(entry) {
63
- const cmd = entry.command || '';
64
- // Los hooks SWL usan el patrón: node hooks/nombre-hook.js
65
- return /node\s+.*hooks\/[a-z-]+\.js/.test(cmd);
63
+ const hooksArr = entry.hooks || [];
64
+ return hooksArr.some(h => {
65
+ const cmd = h.command || '';
66
+ // Los hooks SWL usan el patrón: node hooks/nombre-hook.js
67
+ return /node\s+.*hooks\/[a-z-]+\.js/.test(cmd);
68
+ });
66
69
  }
67
70
 
68
71
  /**
@@ -129,8 +132,11 @@ function registrarHooks(opciones) {
129
132
  }
130
133
 
131
134
  hooksPorEvento[evento].push({
132
- matcher: config.matcher || undefined,
133
- command: generarComando(filename, hooksDir, esGlobal),
135
+ matcher: config.matcher || '',
136
+ hooks: [{
137
+ type: 'command',
138
+ command: generarComando(filename, hooksDir, esGlobal),
139
+ }],
134
140
  });
135
141
  registrados++;
136
142
  }
@@ -143,10 +149,10 @@ function registrarHooks(opciones) {
143
149
 
144
150
  const swlNuevos = hooksPorEvento[evento] || [];
145
151
 
146
- // Limpiar entradas con matcher vacío (Claude Code no necesita la key)
152
+ // Limpiar entradas con matcher vacío (usar "" para match-all)
147
153
  const swlLimpios = swlNuevos.map(h => {
148
- const entry = { command: h.command };
149
- if (h.matcher) entry.matcher = h.matcher;
154
+ const entry = { matcher: h.matcher || '' };
155
+ entry.hooks = h.hooks;
150
156
  return entry;
151
157
  });
152
158
 
@@ -243,8 +249,8 @@ function verificarHooks(settingsPath, hookFiles) {
243
249
 
244
250
  // Buscar si existe un hook SWL que referencie este archivo
245
251
  const encontrado = entradas.find(entry => {
246
- const cmd = entry.command || '';
247
- return cmd.includes(filename);
252
+ const hooksArr = entry.hooks || [];
253
+ return hooksArr.some(h => (h.command || '').includes(filename));
248
254
  });
249
255
 
250
256
  if (!encontrado) {
@@ -253,8 +259,8 @@ function verificarHooks(settingsPath, hookFiles) {
253
259
  }
254
260
 
255
261
  // Verificar matcher correcto
256
- const matcherEsperado = config.matcher || undefined;
257
- const matcherActual = encontrado.matcher || undefined;
262
+ const matcherEsperado = config.matcher || '';
263
+ const matcherActual = encontrado.matcher || '';
258
264
 
259
265
  if (matcherEsperado !== matcherActual) {
260
266
  incorrectos.push(`${filename}: matcher esperado="${matcherEsperado || '(ninguno)'}" actual="${matcherActual || '(ninguno)'}"`);