@saulwade/swl-ses 1.3.7 → 1.3.8

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 — @saulwade/swl-ses v1.3.7
1
+ # CLAUDE.md — @saulwade/swl-ses v1.3.8
2
2
 
3
3
  ## Reglas de máxima prioridad (aplican SIEMPRE, sin excepción)
4
4
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # swl-ses v1.3.7
1
+ # swl-ses v1.3.8
2
2
 
3
3
  > El paquete anterior `@saulwadeleon/swl-software-engineering-system` está deprecado. Migrar a `@saulwade/swl-ses` (npmjs.org canónico) o `@saul-wade/swl-ses` (mirror en GitHub Packages) — el CLI `swl-ses` no cambia.
4
4
 
@@ -17,9 +17,12 @@ Este comando es **complementario a `/swl:compactar`**, no lo reemplaza. Compacta
17
17
  - Saul lo pide explícitamente.
18
18
  - La sesión produjo una decisión arquitectural que afecta a otros proyectos del ecosistema.
19
19
 
20
- ## Paso 0 — Validación del destino
20
+ ## Paso 0 — Validación del destino y canal de escritura
21
21
 
22
- Verifica que el vault existe y es accesible:
22
+ Hay **dos canales** posibles para escribir al vault. El canal preferido es el
23
+ MCP de Obsidian; el filesystem directo es fallback documentado.
24
+
25
+ ### 0a — Validar el vault en filesystem (para lectura y detección)
23
26
 
24
27
  ```bash
25
28
  test -d "F:\Google Drive\Developer\Obsidian\Vault\SWL\00-Inbox" \
@@ -29,6 +32,29 @@ test -d "F:\Google Drive\Developer\Obsidian\Vault\SWL\00-Inbox" \
29
32
 
30
33
  Si la ruta no es accesible (por ejemplo, Google Drive no sincronizado o letra de unidad distinta), **abortar con mensaje claro**. No intentes rutas alternativas sin permiso explícito.
31
34
 
35
+ ### 0b — Detectar disponibilidad del MCP de Obsidian
36
+
37
+ Verifica si los tools `mcp__obsidian__obsidian_append_content` o
38
+ `mcp__obsidian__obsidian_patch_content` están cargados o deferidos:
39
+
40
+ - Si aparecen como **deferred** en `<system-reminder>`, cargar el schema con
41
+ `ToolSearch(query="select:mcp__obsidian__obsidian_append_content", ...)`.
42
+ - Si tras `ToolSearch` siguen sin estar disponibles, el MCP server no está
43
+ corriendo (Obsidian cerrado o plugin Local REST API desactivado). En ese
44
+ caso usar canal de fallback (filesystem directo) — ver Paso 4.
45
+
46
+ **Por qué MCP-first**: el hook `proteccion-rutas.js` bloquea la herramienta
47
+ `Write` con destino fuera del CWD del proyecto. La ruta del vault
48
+ (`F:\Google Drive\...`) siempre cae fuera del CWD si trabajas en
49
+ `D:\Python\<proyecto>\`. El MCP de Obsidian opera vía HTTPS al puerto 27124
50
+ del plugin Local REST API — **no pasa por el hook de filesystem**, así que
51
+ nunca dispara el bloqueo.
52
+
53
+ Defaultear a filesystem cuando el MCP está disponible es un anti-patrón
54
+ documentado en `reglas/consultar-vault-primero.md § Workflow forzoso para
55
+ escritura al vault`. El bloqueo por `proteccion-rutas.js` no es una falla a
56
+ esquivar — es una señal de que el canal correcto es el MCP.
57
+
32
58
  ## Paso 1 — Identificación del proyecto actual
33
59
 
34
60
  Detecta qué proyecto eres leyendo:
@@ -205,25 +231,72 @@ Ejecutar `/sync-projects {proyecto-slug}` en el vault para integrar los cambios
205
231
 
206
232
  ## Paso 4 — Escritura en el vault
207
233
 
208
- Escribe el archivo en:
234
+ El archivo destino es:
209
235
 
210
236
  ```
211
237
  F:\Google Drive\Developer\Obsidian\Vault\SWL\00-Inbox\YYYY-MM-DD_HHMM_export-{proyecto-slug}.md
212
238
  ```
213
239
 
214
- Usar UTF-8 sin BOM. En PowerShell:
240
+ Con UTF-8 sin BOM. Usar **uno de dos canales** según disponibilidad:
241
+
242
+ ### Canal A (preferido) — MCP de Obsidian
243
+
244
+ Si el Paso 0b confirmó que `mcp__obsidian__obsidian_append_content` está
245
+ disponible (cargado directamente o tras `ToolSearch`), usar este canal:
246
+
247
+ ```jsonc
248
+ // La ruta es RELATIVA al vault root (no incluye F:\...\SWL\)
249
+ mcp__obsidian__obsidian_append_content({
250
+ filepath: "00-Inbox/YYYY-MM-DD_HHMM_export-{proyecto-slug}.md",
251
+ content: "<contenido completo del export>"
252
+ })
253
+ ```
254
+
255
+ Ventajas frente al filesystem:
256
+ - **No pasa por `proteccion-rutas.js`** — el MCP opera vía HTTPS al puerto
257
+ 27124, fuera del flujo de Bash/Write/Edit.
258
+ - **Sin staging intermedio**: escribe directamente al archivo final del vault.
259
+ - **Auditable**: el plugin Local REST API de Obsidian registra el acceso.
260
+ - **Cross-OS**: el wrapper funciona idéntico en Windows/macOS/Linux sin
261
+ manejar separators de path.
262
+
263
+ Notas operativas:
264
+ - Si el archivo ya existe con ese timestamp (raro), agregar sufijo `_b`
265
+ al nombre antes de invocar `append_content`. El MCP de obsidian no
266
+ sobreescribe si el archivo existe — `append` agrega al final.
267
+ - Si se necesita escribir secciones específicas en lugar de un archivo
268
+ completo, usar `mcp__obsidian__obsidian_patch_content` con
269
+ `target_type: "heading"`.
270
+
271
+ ### Canal B (fallback) — Filesystem directo
272
+
273
+ Solo cuando el MCP no responde tras `ToolSearch` (Obsidian cerrado, plugin
274
+ desactivado, sin red local). **Esto va a chocar con `proteccion-rutas.js`**
275
+ si el CWD es el directorio del proyecto, así que requiere ejecución vía
276
+ Bash con redirección o vía un comando del CLI nativo del SO:
215
277
 
216
278
  ```powershell
279
+ # PowerShell — UTF-8 sin BOM
217
280
  $encoding = New-Object System.Text.UTF8Encoding($false)
218
281
  [System.IO.File]::WriteAllText($path, $content, $encoding)
219
282
  ```
220
283
 
221
- En Node.js hook o script:
222
-
223
- ```javascript
224
- fs.writeFileSync(path, content, { encoding: 'utf8' });
284
+ ```bash
285
+ # Bash + heredoc — UTF-8 sin BOM por default en Node 18+
286
+ cat > "$path" <<'EOF'
287
+ <contenido del export>
288
+ EOF
225
289
  ```
226
290
 
291
+ **No usar `Write` directo** desde la herramienta del agente — `proteccion-rutas.js`
292
+ lo bloquea. Si por algún motivo el agente necesita usar `Write`, primero
293
+ escribe a `_userland/staging/<timestamp>.md` dentro del CWD, luego mueve con
294
+ `Bash` (`mv` o PowerShell `Move-Item`).
295
+
296
+ Reportar al usuario qué canal se usó:
297
+ - Canal A → `[OK] Vía: MCP Obsidian (puerto 27124)`
298
+ - Canal B → `[OK] Vía: filesystem directo (MCP no disponible)`
299
+
227
300
  ## Paso 5 — Confirmación
228
301
 
229
302
  Reporta al usuario:
@@ -267,6 +340,12 @@ Próximo paso: al abrir el vault, ejecuta:
267
340
  - Duplicar con el `COMPACTACION.md` del proyecto (copiar pega tal cual). El export es una **síntesis para vault**, no un espejo.
268
341
  - Intentar escribir directamente en `02-Projects/` del vault. Eso es zona ⚠️ en el vault — solo Saul decide si promoverlo.
269
342
  - Usar rutas con backslash no escapadas en código generado.
343
+ - **Defaultear a filesystem cuando el MCP de Obsidian está disponible**.
344
+ El bloqueo por `proteccion-rutas.js` no es una falla a esquivar con Bash
345
+ staging — es señal de que el canal correcto es el MCP. Ver Paso 0b.
346
+ - **Recurrir al workaround del filesystem antes de cargar el schema del
347
+ MCP con `ToolSearch`**. Tools deferred ≠ tools ausentes — el MCP server
348
+ está corriendo, solo falta cargar el schema. Cargar antes de defaultear.
270
349
 
271
350
  ## Relación con otros comandos SWL
272
351
 
@@ -285,7 +364,20 @@ Produce:
285
364
 
286
365
  ```
287
366
  [OK] Export creado: F:\Google Drive\Developer\Obsidian\Vault\SWL\00-Inbox\2026-04-16_2130_export-sigaf.md (487 palabras)
367
+ [OK] Vía: MCP Obsidian (puerto 27124)
368
+ [OK] Enlace canónico: [[DEV - SIGAF]]
288
369
 
289
370
  Próximo paso: al abrir el vault, ejecuta:
290
371
  /sync-projects sigaf
291
372
  ```
373
+
374
+ ## Historial de cambios del comando
375
+
376
+ - **v1.3.8** (2026-05-11) — Agregado flujo MCP-first en Paso 4 con detección
377
+ en Paso 0b. Origen: en la sesión v1.3.4 → v1.3.8 el comando defaultó a
378
+ `Write` directo al filesystem que fue bloqueado por `proteccion-rutas.js`.
379
+ El fallback al MCP funcionó pero quedó manual. Esta versión documenta
380
+ el orden de preferencia (MCP primero, filesystem como fallback explícito)
381
+ y agrega la nota de "tools deferred ≠ tools ausentes" en anti-patrones.
382
+ Aplicación de la regla `consultar-vault-primero.md § Workflow forzoso
383
+ para escritura al vault`.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: extractor-de-aprendizajes
3
3
  description: Convertir errores y patrones descubiertos durante la implementación en nuevas habilidades o reglas. Ciclo de mejora continua del sistema SWL.
4
- version: "1.0.3"
4
+ version: "1.0.4"
5
5
  herramientasPermitidas: [Read]
6
6
  exclusiones:
7
7
  - "No cargar para actualizar el perfil del usuario — las correcciones explícitas del usuario van a `instintos/perfil-usuario.yaml` vía `perfilador-usuario-swl`, no a APRENDIZAJES.md."
@@ -10,8 +10,8 @@ exclusiones:
10
10
  - "No cargar si el aprendizaje no tiene causa raíz identificada — documentar síntoma sin causa produce reglas que no previenen el error real."
11
11
  evolvable: true # default para skill estandar
12
12
  evolved: true
13
- evolved-from: "1.1.1"
14
- evolved-at: "2026-05-02"
13
+ evolved-from: "1.0.3"
14
+ evolved-at: "2026-05-11"
15
15
  evolved-by: "aprender"
16
16
  evolved-note: "Extender gotcha Explore (papers → papers+repos) tras confirmación x4 — sync desde skill global"
17
17
  ---
@@ -308,6 +308,10 @@ Durante `/swl:aprender`, aplicar estas reglas:
308
308
 
309
309
  *Para repos externos (Modo B)*: 4 filtros críticos: (1) ¿qué % es teoría/código no-portable vs portable? — si >70% no-portable, recortar; (2) **¿la propuesta reescribe mecanismos existentes en el proyecto destino?** — VERIFICAR con `Grep`/`Read` 2-3 afirmaciones concretas del agente contra el código real ANTES de aceptar (ej: agente dice "X usa Y" → `grep -l Y` para confirmar); (3) ¿LOC nuevas estimadas vs reutilizar lo existente? — si la propuesta supera 500 LOC para un solo patrón, hay sobre-ingeniería; (4) ¿el alcance reducido cubre 80% del valor? — Pareto: identificar el patrón mínimo que captura la mayor parte del beneficio. **Patrón de validación obligatorio**: extraer 2-3 afirmaciones factuales del reporte del Explore (ej: "X usa LiteLLM", "no existe Gleaning en el proyecto") y verificar cada una con `Grep`/`Read` antes de aceptar el plan.
310
310
  - **Hooks de calidad pre-commit bloquean fixtures de tests como falsos positivos**: el hook `calidad-pre-commit.js` aplica regex `\b(api_key|password|token|secret)\s*[=:]\s*["'][^"'\s]{4,}["']` que matchea fixtures legítimos en archivos de test. Caso real: test que valida que la función `sanitizar()` redacta `api_key="abc12345xyz"` se bloquea. Causa: el hook no distingue contexto de test vs producción. Solución: en archivos de test, construir fixtures con concatenación de strings (`'api' + '_key'`, `'pass' + 'word'`) o agregar marcador placeholder reconocido por el hook (`fake_`, `dummy_`, `placeholder`, `example`, `os.environ`). NUNCA bypassear el hook con `--no-verify` — el detector cumple su función; ajustar el fixture es lo correcto.
311
+ - **Regex de path-matching `/[\\/]<dir>[\\/]/` falla con paths relativos sin slash inicial** [CONFIRMADO x4]: hooks que filtran archivos por directorio (ej: `hooks/extraccion-aprendizajes.js` con `PATRONES_ARCHIVO_SWL_EXCLUIDO`) usan patrones que requieren un separator ANTES del nombre. Caso real: path `scripts/lib/foo.js` (sin slash inicial) eludía el filtro de exclusión y generaba placeholders espurios en APRENDIZAJES.md cada vez que se hacía `Edit` o `Write` sobre archivos del sistema SWL. Causa: el regex `[\\/]` requiere un caracter slash/backslash previo; cuando el path empieza con el nombre del directorio directamente, no matchea. Solución: usar `/(?:^|[\\/])<dir>[\\/]/` para aceptar tanto el inicio del string como un separator previo. Evidencia: 4 placeholders eliminados manualmente entre v1.3.3-v1.3.5 antes de identificar la causa raíz; fix endurecido aplicado en v1.3.5 (Fix I).
312
+ - **`git ls-files` es preferible a `fs.readdir` recursivo para tests anti-regresión que escanean el repo**: usar `execSync('git ls-files')` limita el escaneo a archivos versionados — evita `node_modules/`, `.git/`, `_userland/`, archivos temporales y backups sin enumerar exclusiones. Caso real: `tests/scripts/no-legacy-npx-pattern.test.js` v1.3.6 escanea 1000+ archivos versionados en <200ms; el equivalente con `fs.readdir` recursivo más exclusiones manuales sería más lento y propenso a olvidar paths. Cuando el test es de "calidad del repo" (no de comportamiento), `git ls-files` es la primitiva correcta.
313
+ - **Whitelist enumerado versión-por-versión en tests anti-regresión genera deuda perpetua**: un whitelist tipo `RELEASE-NOTES-v1.3.[0-5].md` requiere agregar una entrada con cada release nueva — el test fallará al publicar v1.3.6, v1.3.7, etc. Caso real: v1.3.6 publicó a GitHub Packages pero falló en npmjs porque el whitelist v1.3.5 no cubría el nuevo `RELEASE-NOTES-v1.3.6.md`. Causa: enumeración cuando la categoría es semánticamente catch-all. Solución: si el archivo es histórico inmutable por definición (release notes, ADRs, changelog entries cerrados), usar patrón catch-all `^RELEASE-NOTES-.*\.md$` desde el inicio. Aplicar regla: *si cada release nueva agregaría entry al whitelist, el whitelist está mal diseñado.*
314
+ - **Fix combinado en dos capas (específico A + general B) es más robusto que cada uno aislado** [PATRÓN VALIDADO]: cuando un bug tiene múltiples vectores de entrada, aplicar dos defensas con cobertura distinta. Caso real: `hooks/extraccion-aprendizajes.js` v1.3.4 — Capa A: lista de archivos meta excluidos (`RELEASE-NOTES-*.md`, `RESUMEN.md`, etc.) que filtra por path; Capa B: detector estructural de "contexto solo headings" (>60% líneas son `##`/`###`) que filtra por contenido. Si A falla (archivo con nombre nuevo no en lista), B protege. Si B falsea (heading legítimo en bug real), A asegura. Patrón aplicable a cualquier filtro de seguridad/calidad donde el espacio de inputs hostiles es abierto.
311
315
 
312
316
  ## Anti-patrones del proceso de extracción
313
317
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: swl-claudemd
3
3
  description: Conocimiento operacional para auditar y mantener archivos CLAUDE.md — contrato canónico de secciones (best practices Anthropic, ADR-0016), umbrales de bloat (líneas totales, bullets gigantes, placeholders, @references rotas), reglas de extracción a archivos referenciados con @, y plantillas de inicialización (init-user para ~/.claude/CLAUDE.md, init-project para CLAUDE.md raíz detectando stack). Provee las reglas; el comando /swl:claudemd ejecuta el flujo. Cargar desde ese comando o cuando el hook claudemd-bloat-detector sugiera intervención.
4
- version: "1.0.1"
4
+ version: "1.0.2"
5
5
  herramientasPermitidas: [Read, Write, Edit, Bash, Glob, Grep]
6
6
  exclusiones:
7
7
  - "No cargar para editar reglas globales en ~/.claude/rules/ — usar Edit directo."
@@ -205,6 +205,20 @@ Genera `./CLAUDE.md` raíz del proyecto detectando stack actual.
205
205
  pueden NO tener todas las secciones canónicas (porque heredan del root).
206
206
  Por ahora el auditor aplica el contrato uniforme; si el ADR-0007 se
207
207
  acepta, el auditor debe distinguir root vs subdirectorio.
208
+ - **Codificar el patrón legacy/malo como ejemplo "correcto" en una regla
209
+ de CLAUDE.md codifica el bug**: una regla cuya prosa enseña el patrón
210
+ correcto pero cuyo *ejemplo* muestra el patrón malo se auto-perpetúa.
211
+ Cada release nuevo copia el ejemplo y replica el problema. Caso real:
212
+ CLAUDE.md v1.3.5 línea 59 decía *"todo mensaje del installer/docs usa
213
+ `npx swl-ses@latest <comando>`"* — pero `npx swl-ses@latest` sin scope
214
+ resuelve al paquete legacy DEPRECATED tras el rebrand 2026-04-30. La
215
+ regla acumuló 152 ocurrencias del patrón malo en 8 releases consecutivos
216
+ hasta v1.3.6. Solución: las reglas DEBEN mostrar el patrón correcto en
217
+ el ejemplo. Si la regla tiene que citar un patrón malo (para
218
+ prohibirlo), envolverlo en bloque "NUNCA" explícito separado del
219
+ ejemplo de uso correcto. Pregunta de auditoría: *si un autor de release
220
+ futuro copia el ejemplo de esta regla literalmente, ¿produce código
221
+ correcto?* Si no, la regla está mal escrita.
208
222
 
209
223
  ## Señales de alerta
210
224
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "lockfileVersion": 1,
3
- "generatedAt": "2026-05-11T22:33:40.056Z",
3
+ "generatedAt": "2026-05-11T22:55:18.517Z",
4
4
  "skillsCount": 155,
5
- "lockHash": "sha256:32199636eb3c585dd1090cb9f6081aaaaef886241b304c697b2eaf27fd0303ca",
5
+ "lockHash": "sha256:b4860049091d23b9e822f9b2930f5d1bfb19cd9299fa074e4bb71852518769cc",
6
6
  "skills": [
7
7
  {
8
8
  "nombre": "accesibilidad-a11y",
@@ -441,9 +441,9 @@
441
441
  {
442
442
  "nombre": "extractor-de-aprendizajes",
443
443
  "path": "habilidades/extractor-de-aprendizajes/SKILL.md",
444
- "hash": "sha256:2e791dc7c05395272e7de47573daac087faa99142023a22c29e24b3f749b8cd3",
445
- "bytes": 17541,
446
- "version": "\"1.0.3\""
444
+ "hash": "sha256:4e7ec2961f7c4c6bc52759516a1d7f9f9c839883c09b95951f0c68b4d803ad3d",
445
+ "bytes": 20527,
446
+ "version": "\"1.0.4\""
447
447
  },
448
448
  {
449
449
  "nombre": "fastapi-experto",
@@ -952,9 +952,9 @@
952
952
  {
953
953
  "nombre": "swl-claudemd",
954
954
  "path": "habilidades/swl-claudemd/SKILL.md",
955
- "hash": "sha256:18f56f2c9d19e0671a42b47186465b04246ac38c41ec058440c25d683a57b92b",
956
- "bytes": 10578,
957
- "version": "\"1.0.1\""
955
+ "hash": "sha256:18cef250bd32a7841db3b6362b9303679bf2851e5e1efe7f3d81f0dd514ec5eb",
956
+ "bytes": 11585,
957
+ "version": "\"1.0.2\""
958
958
  },
959
959
  {
960
960
  "nombre": "swl-dashboard",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saulwade/swl-ses",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot con 59 agentes, 155 habilidades, 43 comandos, 64 reglas y 41 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
5
  "bin": {
6
6
  "swl-ses": "bin/swl-ses.js",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swl-ses",
3
- "version": "1.3.7",
3
+ "version": "1.3.8",
4
4
  "description": "Sistema de ingenieria de software auto-evolutivo multi-runtime polyglot. 59 agentes, 155 habilidades, 43 comandos, 64 reglas y 41 hooks. 62 librerias. 11 lenguajes. Soporta Claude Code, Copilot, OpenCode, Codex y Gemini CLI.",
5
5
  "author": "Saul Wade Leon",
6
6
  "license": "MIT",