@saulwade/swl-ses 1.2.1 → 1.3.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.
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: claudemd-bloat-detector.js
6
+ * Tipo: PostToolUse (aplica a: Write, Edit, MultiEdit)
7
+ *
8
+ * Ejecuta `scripts/auditar-claudemd.js` contra archivos `CLAUDE.md`
9
+ * recién modificados y emite un nudge a `.planning/evolucion/nudges.jsonl`
10
+ * si el veredicto es WARN o ERROR.
11
+ *
12
+ * Aplica ADR-0016 (best practices Anthropic "The CLAUDE.md file"):
13
+ * detecta inflación (líneas excesivas, bullets monolíticos, secciones
14
+ * canónicas ausentes, ausencia de @references) y sugiere intervención
15
+ * con `/swl:claudemd refactor`.
16
+ *
17
+ * Opt-out: SWL_CLAUDEMD_BLOAT=0 desactiva completamente el hook.
18
+ *
19
+ * Comportamiento:
20
+ * - Nunca bloquea operaciones (exit code 0 siempre)
21
+ * - Solo emite nudge cuando veredicto != OK — ruido mínimo
22
+ * - Solo se dispara con archivos cuyo basename sea exactamente CLAUDE.md
23
+ * - Respeta exclusiones: temp/, node_modules/, respositorios-git/
24
+ *
25
+ * Formato del nudge:
26
+ * {
27
+ * id: string,
28
+ * kind: "claudemd-bloat",
29
+ * target: "documentador-swl",
30
+ * source: "hooks/claudemd-bloat-detector.js",
31
+ * message: "...",
32
+ * data: { archivo, veredicto, lineas, hallazgos_count },
33
+ * ts: ISO,
34
+ * accionado: false
35
+ * }
36
+ */
37
+
38
+ const fs = require('fs');
39
+ const path = require('path');
40
+ const crypto = require('crypto');
41
+
42
+ // ─── Opt-out global ───────────────────────────────────────────────────────
43
+ if (process.env.SWL_CLAUDEMD_BLOAT === '0') {
44
+ process.exit(0);
45
+ }
46
+
47
+ let hookInput = '';
48
+ try {
49
+ hookInput = fs.readFileSync(0, 'utf-8');
50
+ } catch (_) {
51
+ process.exit(0);
52
+ }
53
+
54
+ let evento;
55
+ try {
56
+ evento = JSON.parse(hookInput);
57
+ } catch (_) {
58
+ process.exit(0);
59
+ }
60
+
61
+ const toolName = evento?.tool_name;
62
+ const toolInput = evento?.tool_input;
63
+
64
+ if (!toolName || !['Write', 'Edit', 'MultiEdit'].includes(toolName)) {
65
+ process.exit(0);
66
+ }
67
+
68
+ const filePath = toolInput?.file_path;
69
+ if (!filePath) {
70
+ process.exit(0);
71
+ }
72
+
73
+ // Solo CLAUDE.md (basename exacto, case-sensitive)
74
+ const basename = path.basename(filePath);
75
+ if (basename !== 'CLAUDE.md') {
76
+ process.exit(0);
77
+ }
78
+
79
+ const pathNormalized = filePath.replace(/\\/g, '/');
80
+ const RUTAS_EXCLUIDAS = [
81
+ '/temp/',
82
+ '/node_modules/',
83
+ '/respositorios-git/',
84
+ '/.planning/',
85
+ ];
86
+ if (RUTAS_EXCLUIDAS.some((excluida) => pathNormalized.includes(excluida))) {
87
+ process.exit(0);
88
+ }
89
+
90
+ // El archivo debe existir
91
+ if (!fs.existsSync(filePath)) {
92
+ process.exit(0);
93
+ }
94
+
95
+ // ─── Ejecutar auditor (módulo, no subproceso) ─────────────────────────────
96
+ const CWD = process.cwd();
97
+ const auditorPath = path.join(CWD, 'scripts', 'auditar-claudemd.js');
98
+ if (!fs.existsSync(auditorPath)) {
99
+ // No hay auditor instalado en este destino; salir silenciosamente
100
+ process.exit(0);
101
+ }
102
+
103
+ let resultado;
104
+ try {
105
+ const { auditar } = require(auditorPath);
106
+ resultado = auditar(filePath);
107
+ } catch (_) {
108
+ // Cualquier error del auditor: salir silenciosamente, no romper el hook
109
+ process.exit(0);
110
+ }
111
+
112
+ // Solo emitir nudge si veredicto != OK
113
+ if (!resultado || resultado.veredicto === 'OK') {
114
+ process.exit(0);
115
+ }
116
+
117
+ // ─── Construir nudge ──────────────────────────────────────────────────────
118
+ const rutaRelativa = path.relative(CWD, filePath).replace(/\\/g, '/');
119
+ const topHallazgos = (resultado.hallazgos || [])
120
+ .slice(0, 3)
121
+ .map((h) => ` - [${h.severidad}] ${h.mensaje}`)
122
+ .join('\n');
123
+
124
+ const nudge = {
125
+ id: crypto.randomBytes(8).toString('hex'),
126
+ kind: 'claudemd-bloat',
127
+ target: 'documentador-swl',
128
+ source: 'hooks/claudemd-bloat-detector.js',
129
+ message:
130
+ `[claudemd] ${rutaRelativa} veredicto: ${resultado.veredicto} ` +
131
+ `(${resultado.hallazgos.length} hallazgos)\n` +
132
+ topHallazgos + '\n' +
133
+ ` Ejecutar \`/swl:claudemd audit\` para detalle, ` +
134
+ `\`/swl:claudemd refactor\` para sugerencias de extracción.`,
135
+ data: {
136
+ archivo: rutaRelativa,
137
+ veredicto: resultado.veredicto,
138
+ lineas: resultado.metricas?.lineas,
139
+ secciones_ausentes: resultado.metricas?.secciones_ausentes || [],
140
+ tiene_at_references: resultado.metricas?.tiene_at_references,
141
+ hallazgos_count: resultado.hallazgos.length,
142
+ },
143
+ ts: new Date().toISOString(),
144
+ accionado: false,
145
+ accionado_ts: null,
146
+ accionado_por: null,
147
+ };
148
+
149
+ // ─── Persistir a nudges.jsonl ─────────────────────────────────────────────
150
+ try {
151
+ const nudgesPath = path.join(CWD, '.planning', 'evolucion', 'nudges.jsonl');
152
+ const nudgesDir = path.dirname(nudgesPath);
153
+ if (!fs.existsSync(nudgesDir)) {
154
+ fs.mkdirSync(nudgesDir, { recursive: true });
155
+ }
156
+ fs.appendFileSync(nudgesPath, JSON.stringify(nudge) + '\n', 'utf-8');
157
+ } catch (_) {
158
+ // No fallar el hook por error de escritura
159
+ }
160
+
161
+ process.exit(0);
@@ -347,6 +347,15 @@
347
347
  "maxConsecutiveFailures": 5,
348
348
  "degradeOnFailure": "skip"
349
349
  },
350
+ "claudemd-bloat-detector.js": {
351
+ "event": "PostToolUse",
352
+ "matcher": "Write|Edit|MultiEdit",
353
+ "description": "Ejecuta scripts/auditar-claudemd.js contra archivos CLAUDE.md recién modificados (basename exacto, no cualquier .md). Emite nudge a .planning/evolucion/nudges.jsonl si veredicto != OK (líneas excesivas, bullets gigantes, secciones canónicas ausentes, sin @references, placeholders). Aplica ADR-0016 (best practices Anthropic 'The CLAUDE.md file'). No bloquea. Excluye temp/, node_modules/, respositorios-git/, .planning/. Opt-out: SWL_CLAUDEMD_BLOAT=0.",
354
+ "blocking": false,
355
+ "async": true,
356
+ "maxConsecutiveFailures": 5,
357
+ "degradeOnFailure": "skip"
358
+ },
350
359
  "notificacion-telegram.js": {
351
360
  "event": "Stop",
352
361
  "matcher": "",
@@ -698,11 +698,12 @@
698
698
  ]
699
699
  },
700
700
  "habilidades-swl-herramientas": {
701
- "descripcion": "Herramientas internas SWL: markitdown, revisar-impacto, NestJS",
701
+ "descripcion": "Herramientas internas SWL: markitdown, revisar-impacto, claudemd, NestJS",
702
702
  "tipo": "habilidades",
703
703
  "archivos": [
704
704
  "habilidades/swl-markitdown",
705
705
  "habilidades/swl-revisar-impacto",
706
+ "habilidades/swl-claudemd",
706
707
  "habilidades/nestjs-experto"
707
708
  ],
708
709
  "targets": [
@@ -801,7 +802,8 @@
801
802
  "comandos/swl/exportar-vault.md",
802
803
  "comandos/swl/ayuda.md",
803
804
  "comandos/swl/inbox.md",
804
- "comandos/swl/reflect-skills.md"
805
+ "comandos/swl/reflect-skills.md",
806
+ "comandos/swl/claudemd.md"
805
807
  ],
806
808
  "targets": [
807
809
  "claude",
@@ -956,6 +958,7 @@
956
958
  "hooks/captura-feedback-usuario.js",
957
959
  "hooks/inbox-aviso.js",
958
960
  "hooks/aiisms-detector.js",
961
+ "hooks/claudemd-bloat-detector.js",
959
962
  "hooks/sugerir-regenerar-inventario.js",
960
963
  "hooks/sugerir-contribuir.js",
961
964
  "hooks/_run-hook.sh",
@@ -1136,6 +1139,22 @@
1136
1139
  "gemini"
1137
1140
  ]
1138
1141
  },
1142
+ "claudemd-auditor": {
1143
+ "descripcion": "Auditor de calidad de CLAUDE.md según best practices Anthropic (ADR-0016). Detecta inflación (líneas excesivas, bullets gigantes, secciones canónicas ausentes, sin @references, placeholders). Usado por el comando /swl:claudemd y por el hook claudemd-bloat-detector. Zero-deps. Soporta --json y --strict. Umbrales configurables: SWL_CLAUDEMD_MAX_LINES (default 200), SWL_CLAUDEMD_MAX_BULLET_CHARS (default 1000).",
1144
+ "tipo": "scripts",
1145
+ "archivos": [
1146
+ "scripts/auditar-claudemd.js",
1147
+ "docs/variables-entorno.md"
1148
+ ],
1149
+ "targets": [
1150
+ "claude",
1151
+ "openclaude",
1152
+ "copilot",
1153
+ "opencode",
1154
+ "codex",
1155
+ "gemini"
1156
+ ]
1157
+ },
1139
1158
  "mcp-server-swl": {
1140
1159
  "descripcion": "MCP server stub experimental que expone memoria SWL (aprendizajes, sesiones, instintos) a clientes MCP externos (Cursor, Gemini CLI, OpenCode, Cline, Claude Desktop). Modo stdio. 3 endpoints: swl_memory_search, swl_aprendizajes_recientes, swl_instintos_activos. SIN auth, SIN rate limiting, SIN HTTP transport, SIN tests integración. NO USAR EN PRODUCCIÓN. Trigger para hardening: uso real ≥2 runtimes diferentes consistentemente por ≥1 mes. El binario `swl-mcp-server` se instala automáticamente vía npm install -g (declarado en package.json bin). NO se propaga al runtime SWL — vive en el paquete npm como herramienta opt-in. Ver scripts/mcp-server/README.md para 11 limitaciones explícitas y diseño futuro.",
1141
1160
  "tipo": "scripts",
package/package.json CHANGED
@@ -1,87 +1,87 @@
1
- {
2
- "name": "@saulwade/swl-ses",
3
- "version": "1.2.1",
4
- "description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 59 agentes, 151 habilidades, 42 comandos, 64 reglas y 40 hooks. Soporta 11 lenguajes y 5 runtimes: Claude Code, Copilot, OpenCode, Codex y Gemini CLI. 100% en espanol (Mexico). Incluye gateway bidireccional con relay Telegram a Claude Code.",
5
- "bin": {
6
- "swl-ses": "bin/swl-ses.js",
7
- "swl-telegram-bot": "bin/swl-telegram-bot.js",
8
- "swl-mcp-server": "bin/swl-mcp-server.js"
9
- },
10
- "files": [
11
- "bin",
12
- "scripts",
13
- "manifiestos",
14
- "agentes",
15
- "habilidades",
16
- "comandos",
17
- "reglas",
18
- "hooks",
19
- "plantillas",
20
- "contextos",
21
- "instintos",
22
- "schemas",
23
- "_userland",
24
- "plugin.json",
25
- "CLAUDE.md"
26
- ],
27
- "scripts": {
28
- "postinstall": "echo '\n swl-software-engineering-system instalado.\n Ejecuta: npx swl-ses init\n'",
29
- "test": "node --test tests/lib/*.test.js tests/scripts/*.test.js tests/scripts/lib/*.test.js tests/hooks/*.test.js",
30
- "test:validate": "node scripts/validar.js",
31
- "test:manifest": "node scripts/validar-manifest.js",
32
- "test:smoke": "node scripts/smoke-test.js",
33
- "test:aislamiento": "node scripts/validar-tests-aislamiento.js",
34
- "test:all": "npm test && node scripts/validar.js && node scripts/validar-manifest.js",
35
- "test:userland": "node scripts/validar-userland-vacio.js",
36
- "test:release": "npm run test:all && npm run test:userland && npm run test:smoke",
37
- "doctor": "node scripts/doctor.js",
38
- "prepack": "node scripts/limpiar-artefactos-python.js && node scripts/validar-userland-vacio.js",
39
- "prepublishOnly": "npm run test:release",
40
- "publish:all": "node scripts/publicar.js",
41
- "publish:github": "node scripts/publicar.js --solo-github",
42
- "publish:npmjs": "node scripts/publicar.js --solo-npmjs",
43
- "publish:dry": "node scripts/publicar.js --dry-run",
44
- "generate:docs": "node scripts/generar-inventario.js",
45
- "gen-checklists": "node scripts/generar-checklists-consolidados.js",
46
- "gen-checklists:check": "node scripts/generar-checklists-consolidados.js --check",
47
- "field-report": "node scripts/field-report.js",
48
- "configure:branch-protection": "node scripts/configurar-branch-protection.js"
49
- },
50
- "engines": {
51
- "node": ">=22.0.0"
52
- },
53
- "keywords": [
54
- "claude-code",
55
- "github-copilot",
56
- "gemini-cli",
57
- "opencode",
58
- "codex-cli",
59
- "agentes",
60
- "skills",
61
- "multi-runtime",
62
- "spec-driven",
63
- "orquestacion",
64
- "ingenieria-software"
65
- ],
66
- "author": "Saul Wade Leon",
67
- "license": "MIT",
68
- "repository": {
69
- "type": "git",
70
- "url": "git+https://github.com/saul-wade/swl-ses.git"
71
- },
72
- "homepage": "https://github.com/saul-wade/swl-ses#readme",
73
- "bugs": {
74
- "url": "https://github.com/saul-wade/swl-ses/issues"
75
- },
76
- "publishConfig": {
77
- "registry": "https://registry.npmjs.org/",
78
- "access": "public"
79
- },
80
- "dependencies": {
81
- "docx": "^9.6.1"
82
- },
83
- "overrides": {
84
- "pako": "^2.1.0",
85
- "readable-stream": "^4.7.0"
86
- }
87
- }
1
+ {
2
+ "name": "@saulwade/swl-ses",
3
+ "version": "1.3.0",
4
+ "description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 59 agentes, 154 habilidades, 42 comandos, 64 reglas y 40 hooks. Soporta 11 lenguajes y 5 runtimes: Claude Code, Copilot, OpenCode, Codex y Gemini CLI. 100% en espanol (Mexico). Incluye gateway bidireccional con relay Telegram a Claude Code.",
5
+ "bin": {
6
+ "swl-ses": "bin/swl-ses.js",
7
+ "swl-telegram-bot": "bin/swl-telegram-bot.js",
8
+ "swl-mcp-server": "bin/swl-mcp-server.js"
9
+ },
10
+ "files": [
11
+ "bin",
12
+ "scripts",
13
+ "manifiestos",
14
+ "agentes",
15
+ "habilidades",
16
+ "comandos",
17
+ "reglas",
18
+ "hooks",
19
+ "plantillas",
20
+ "contextos",
21
+ "instintos",
22
+ "schemas",
23
+ "_userland",
24
+ "plugin.json",
25
+ "CLAUDE.md"
26
+ ],
27
+ "scripts": {
28
+ "postinstall": "echo '\n swl-software-engineering-system instalado.\n Ejecuta: npx swl-ses init\n'",
29
+ "test": "node --test tests/lib/*.test.js tests/scripts/*.test.js tests/scripts/lib/*.test.js tests/hooks/*.test.js",
30
+ "test:validate": "node scripts/validar.js",
31
+ "test:manifest": "node scripts/validar-manifest.js",
32
+ "test:smoke": "node scripts/smoke-test.js",
33
+ "test:aislamiento": "node scripts/validar-tests-aislamiento.js",
34
+ "test:all": "npm test && node scripts/validar.js && node scripts/validar-manifest.js",
35
+ "test:userland": "node scripts/validar-userland-vacio.js",
36
+ "test:release": "npm run test:all && npm run test:userland && npm run test:smoke",
37
+ "doctor": "node scripts/doctor.js",
38
+ "prepack": "node scripts/limpiar-artefactos-python.js && node scripts/validar-userland-vacio.js",
39
+ "prepublishOnly": "npm run test:release",
40
+ "publish:all": "node scripts/publicar.js",
41
+ "publish:github": "node scripts/publicar.js --solo-github",
42
+ "publish:npmjs": "node scripts/publicar.js --solo-npmjs",
43
+ "publish:dry": "node scripts/publicar.js --dry-run",
44
+ "generate:docs": "node scripts/generar-inventario.js",
45
+ "gen-checklists": "node scripts/generar-checklists-consolidados.js",
46
+ "gen-checklists:check": "node scripts/generar-checklists-consolidados.js --check",
47
+ "field-report": "node scripts/field-report.js",
48
+ "configure:branch-protection": "node scripts/configurar-branch-protection.js"
49
+ },
50
+ "engines": {
51
+ "node": ">=22.0.0"
52
+ },
53
+ "keywords": [
54
+ "claude-code",
55
+ "github-copilot",
56
+ "gemini-cli",
57
+ "opencode",
58
+ "codex-cli",
59
+ "agentes",
60
+ "skills",
61
+ "multi-runtime",
62
+ "spec-driven",
63
+ "orquestacion",
64
+ "ingenieria-software"
65
+ ],
66
+ "author": "Saul Wade Leon",
67
+ "license": "MIT",
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "git+https://github.com/saul-wade/swl-ses.git"
71
+ },
72
+ "homepage": "https://github.com/saul-wade/swl-ses#readme",
73
+ "bugs": {
74
+ "url": "https://github.com/saul-wade/swl-ses/issues"
75
+ },
76
+ "publishConfig": {
77
+ "registry": "https://registry.npmjs.org/",
78
+ "access": "public"
79
+ },
80
+ "dependencies": {
81
+ "docx": "^9.6.1"
82
+ },
83
+ "overrides": {
84
+ "pako": "^2.1.0",
85
+ "readable-stream": "^4.7.0"
86
+ }
87
+ }