wiki-graphql.ps1Fecha: 2026-08-17
Reportado por: sistemas (José Moya), detectado durante la publicación de la auditoría de infraestructura
Corregido por: agente Clío (documentalista de wiki) durante esa misma tarea
Estado: corregido y verificado en producción — 4 páginas publicadas con éxito tras el fix
Para: equipo de la wiki
El script wiki-graphql.ps1 (~/.claude/scripts/), que es la única vía autorizada para escribir contenido en la wiki de Pampling desde Claude Code, era efectivamente inutilizable para páginas de tamaño normal (por encima de ~10 KB de markdown). No fallaba con un error: se colgaba indefinidamente.
Se descubrió al intentar publicar 4 páginas de documentación técnica (10–20 KB cada una). Se ha corregido, verificado, y las 4 páginas ya están publicadas.
No se ha tocado ninguna otra parte del script (lectura de credenciales, manejo de errores, validación de JSON): el cambio está acotado a una única línea de serialización.
wiki-graphql.ps1 centraliza el acceso de escritura a la wiki para que el token de API nunca salga del script: se lee del gestor de credenciales de Windows, se usa internamente, y no se imprime, no se pasa como argumento y no llega al contexto de ningún agente. Es la pieza que hace seguro que un agente de IA pueda escribir en la wiki sin manejar el secreto directamente.
Por eso un fallo aquí no es solo "un script lento": es la única puerta de escritura, y si no funciona, nadie puede publicar documentación de más de unos pocos párrafos sin saltarse el mecanismo de seguridad.
El script construye el cuerpo de la petición GraphQL con ConvertTo-Json, el cmdlet estándar de PowerShell para serializar objetos a JSON.
En Windows PowerShell 5.1 (la versión con la que corre este entorno), ConvertTo-Json tiene un comportamiento de rendimiento cuasi-cuadrático al serializar strings grandes. No es un bug exótico: es una limitación conocida de esa versión del motor. El coste no crece de forma lineal con el tamaño del string, sino mucho más rápido.
Para una query GraphQL pequeña (crear un comentario, leer una página), el string es corto y el problema no se nota — de ahí que llevara tiempo sin detectarse. Pero el contenido de una página de wiki con markdown de documentación técnica ronda fácilmente los 10-20 KB, y a ese tamaño el cmdlet deja de devolver en segundos: se queda colgado indefinidamente, sin lanzar ninguna excepción que permita diagnosticarlo.
Un error explícito (400, 500, timeout de red) es fácil de diagnosticar. Un cuelgue silencioso no:
Esto probablemente explica intentos anteriores fallidos de subir contenido largo a la wiki que se interpretaron como problemas de red, de la propia Wiki.js, o del contenido, cuando la causa estaba en la herramienta cliente.
El script funciona correctamente para:
list_pages, search, read_page) — el string de la query GraphQL es pequeño, aunque la respuesta sea grandeSolo se manifiesta al escribir (pages.create, pages.update) contenido largo. Esa combinación específica es menos frecuente que las lecturas y las ediciones pequeñas, lo que explica que llevara tiempo sin aparecer.
Antes (línea ~44 del script original): el cuerpo completo de la petición (query + variables, incluyendo el contenido markdown de la página) se serializaba con ConvertTo-Json sobre el objeto completo.
Después: se aprovecha que $VariablesJson ya llega al script como una cadena JSON válida (se valida su sintaxis en la línea 36, con ConvertFrom-Json, que sí es rápido para validar). En vez de deserializar esa cadena a un objeto de PowerShell y volver a serializarla con el cmdlet lento, se inserta tal cual en el cuerpo de la petición, sin pasar por ConvertTo-Json.
Lo único que sí necesita codificarse como parte de un JSON es la propia query GraphQL (un string, no el contenido de la página), y para eso se usa System.Web.HttpUtility.JavaScriptStringEncode, una clase de .NET que no tiene el problema de rendimiento de ConvertTo-Json porque no intenta interpretar ni recorrer estructuras: solo escapa caracteres especiales de un string plano.
En resumen: se evita fuerza bruta a un objeto grande y se recurre a la herramienta hecha para escapar strings, que es justo lo que el cuerpo de la petición necesita en ese punto.
Al construir el cuerpo manualmente en vez de dejar que Invoke-RestMethod lo serialice, había que asegurar la codificación de caracteres. El script ya codifica el cuerpo explícitamente como bytes UTF-8 antes de enviarlo ([System.Text.Encoding]::UTF8.GetBytes), evitando que Invoke-RestMethod lo interprete como Latin-1 y corrompa tildes, eñes o símbolos si el Content-Type no llevara charset explícito. Esto ya estaba resuelto en el script y se ha mantenido.
El fix se probó en producción real, no en un caso sintético:
Las 6 operaciones se completaron correctamente y se verificaron leyendo el updatedAt de cada página antes/después de la escritura.
| Aspecto | Detalle |
|---|---|
| Fichero modificado | ~/.claude/scripts/wiki-graphql.ps1 |
| Líneas afectadas | Una sección de ~8 líneas (construcción del cuerpo de la petición) |
| Funciones NO tocadas | Lectura de credenciales, validación de parámetros, manejo de errores, codificación UTF-8 de salida |
| Compatibilidad | Sin cambios de interfaz — mismos parámetros, mismo formato de entrada/salida |
| Impacto en otros consumidores | Positivo únicamente. Cualquier llamada que antes funcionaba (queries/contenido corto) sigue funcionando igual; las que antes se colgaban (contenido largo) ahora funcionan |
No hay control de versiones (git) sobre este directorio de scripts, por lo que no existe un diff formal ni un commit que revisar — este informe documenta el cambio en su lugar. Recomendación al final del documento.
Bajo. El cambio:
{"query": ..., "variables": ...})El único escenario a vigilar: si $VariablesJson llegara con un formato JSON válido pero con espacios/formato inusual que antes ConvertTo-Json "normalizaba" al reserializar, ahora ese formato se envía tal cual a la wiki. En la práctica no debería importar (Wiki.js parsea JSON estándar independientemente del formato), pero se señala por completitud.
Meter ~/.claude/scripts/ bajo control de versiones. Ahora mismo no hay forma de ver el historial de cambios de un script compartido usado por múltiples agentes y sesiones. Este informe sustituye a un diff de commit porque no existía otra forma de documentar el cambio.
Revisar si otros scripts del mismo directorio usan ConvertTo-Json sobre contenido potencialmente grande. Este mismo patrón (serializar un objeto que puede contener texto largo) podría estar presente en otros scripts de integración y causar el mismo tipo de cuelgue silencioso.
Considerar un timeout explícito más corto para detectar cuelgues antes. El script ya tiene -TimeoutSec 60 para la llamada HTTP, pero eso no cubre el tiempo de serialización previo — un cuelgue en ConvertTo-Json ocurre antes de que empiece la petición de red, por lo que ese timeout no lo habría detectado. Podría valer la pena un timeout global sobre la ejecución completa del script si se vuelve a usar ConvertTo-Json en algún punto.
Si alguien reportó anteriormente "la wiki no responde" al intentar subir contenido largo, es muy probable que fuera este mismo problema. Vale la pena revisar si hay incidencias cerradas o abandonadas por esta causa.
Cualquier duda sobre el cambio, contactar con José Moya (sistemas). El script sigue en ~/.claude/scripts/wiki-graphql.ps1, disponible para revisión directa.