Saltar al contenido principal

Clepit

De un vistazo

Categoría
Plataforma para desarrolladores
Sitio web
clepit.com
Consola
app.clepit.com
Documentación
clepit.com/en/docs
API de GraphQL
api.clepit.com/graphql
Tiempo real
ws.clepit.com
Superficie MCP
api.clepit.com/mcp
Páginas publicadas
clepit.space

La mayor parte del texto con formato acaba en la base de datos como un bloque de HTML. Eso basta mientras no quieras hacer con él nada más que volver a mostrarlo: encontrar todas las páginas que mencionan a un cliente, presentar el mismo documento en una página web, un correo y una aplicación móvil, o dejar que dos personas lo editen a la vez sin que una de ellas pierda un párrafo. A esas alturas las palabras y su formato están enredados, y lo único capaz de leer el documento con fiabilidad es el editor que lo escribió.

Clepit mantiene ambas cosas separadas. Una página es una lista de bloques, cada uno un pequeño objeto con tipo, y el documento es JSON: no hay marcado que analizar ni hace falta un editor para leerlo. Por eso mismo el editor se sostiene solo. @clepit/core se publica en npm con licencia MIT y no sabe nada del lado alojado, mientras que el espacio de trabajo en app.clepit.com es en lo que se convierten esos mismos documentos cuando reciben colaboradores, permisos, historial y una dirección en la web pública.

Una página es una lista de bloques

Un bloque son cuatro campos: un id, un tipo, los datos que ese tipo define y los ajustes que se le hayan aplicado. Los datos de un párrafo tienen una forma distinta de los de una tabla, y es el tipo el que dice qué forma esperar, de modo que un documento guardado puede comprobarse y no solo analizarse. Una página entera es una marca de tiempo, una versión y los bloques en orden, lo bastante pequeña para leerla con los propios ojos y revisarla en un pull request. Nada en ella describe cómo debe verse la página: eso corresponde a lo que la dibuje, y es lo que permite que un mismo documento se convierta en página web, en correo y en pantalla de móvil sin que existan tres copias suyas.

Dibujar un documento sin navegador

El renderizador nunca escribe directamente en el navegador. Dibuja a través de una capa delgada con dos soportes detrás: uno construye nodos reales de página y otro construye una cadena de texto, y el mismo código de bloque se ejecuta en ambos. Así es como una página publicada se dibuja en un servidor donde no existe navegador alguno, y por eso lo que produce el servidor es el mismo documento que habría mostrado el editor, y no una segunda implementación abandonada a la deriva. El soporte de texto exige un saneador como argumento obligatorio y adrede no tiene valor por defecto: el saneador habitual del paquete construye una página para poder analizar, de modo que allí no puede ejecutarse, y recurrir en silencio al escapado despojaría a todos los documentos de su formato interno sin decirlo. La carencia queda así a la vista en el lugar donde se usa, en vez de esconderse en un valor por defecto.

Leer no le cuesta al lector ningún JavaScript

El adaptador de React entrega sus dos mitades por separado, porque quieren cosas opuestas. El componente de contenido se ejecuta en el servidor y emite marcado terminado mientras se construye la página, de modo que el lector recibe el documento en la primera respuesta. El componente de edición vive solo en el cliente, ya que se hace cargo del ciclo de vida del editor, y no hay nada de lo que hacerse cargo hasta que existe un navegador. Leer un documento de Clepit no necesita, por tanto, ningún JavaScript. Es al escribir cuando llega el entorno de ejecución.

Lo que puede contener una página

El paquete trae veintiséis clases de bloque. La mayoría son las que necesita cualquier editor: títulos, párrafos, listas, listas de tareas, citas, código, tablas, imágenes, audio, vídeo, archivos, avisos y separadores. Los demás existen porque escribir documentación pide cosas que una herramienta de escritura suele pasar por alto. Un índice que se construye solo a partir de los títulos del documento y enlaza con cada uno. Secciones plegables y columnas. Una tarjeta que hace las veces de otra página. Un boceto a mano alzada. Y un bloque de actividad que guarda qué documento vigilar, y no una copia de su actividad, de modo que sigue mostrando lo que ocurre ahora en lugar de congelarse el día en que se insertó. El formato dentro de un bloque abarca las marcas de siempre, negrita, cursiva, subrayado, tachado, código en línea, resaltado y enlaces, junto con notas emergentes, etiquetas de estado y menciones. El paquete en sí no tiene dependencia alguna en tiempo de ejecución.

Fórmulas y diagramas, dibujados dentro del paquete

Dos de esos bloques representan LaTeX y Mermaid, y ambos hacen todo el trabajo dentro del paquete: analizan la fuente, calculan la disposición, dibujan el resultado. No hay biblioteca de dibujo por debajo ni llamada a servicio alguno para convertir una fórmula o un diagrama de flujo en una imagen. Eso es menos una preferencia sobre dependencias que una consecuencia del soporte de texto. Un bloque que echara mano de algo que solo brinda un navegador, o de la red, no podría dibujarse en el servidor que sirve las páginas publicadas, y una misma página pasaría entonces a verse distinta según quién la pidiera.

Una referencia de API que vive en la página

Dele al bloque de OpenAPI una especificación, pegada o señalada por una dirección, y dibujará lo que esa especificación describe: las operaciones, sus rutas y parámetros, los esquemas de petición y respuesta, y el método de autenticación. Para cada operación construye además un fragmento de petición en cURL, TypeScript, Dart y Python, generado a partir de la especificación en lugar de escrito a mano por un autor que se olvidará de actualizarlo. El bloque de incrustación mira al mundo exterior del mismo modo: reconoce un puñado de servicios que de verdad puede mostrar, trata para todo lo demás un simple enlace como un resultado legítimo y no como un fracaso, y se niega en redondo a dibujar una dirección en la que no confía.

Dos personas en el mismo párrafo

Una página que se está editando en vivo la sostiene una sola tarea en el servidor, una por página, y todos los cambios pasan por ella en orden. Eso es lo que hace que la edición simultánea siga siendo razonable: no hay un segundo escritor compitiendo con el primero. El documento mismo es un CRDT, así que dos personas escribiendo en el mismo párrafo se fusionan en vez de borrarse, y un cliente que se ha quedado atrás se pone al día intercambiando lo que le falta a cada lado. Cada cambio se añade a un registro de escritura anticipada antes de difundirse a nadie, de modo que lo que ven las demás personas en el documento ya quedó registrado de forma duradera y no solo retransmitido. El permiso lo impone el servidor y no la interfaz: quien se une sin derecho de edición queda rebajado a lectura, y la sesión vuelve a comprobar ese derecho de vez en cuando mientras el documento está abierto, así que un acceso retirado alcanza a alguien que ya está escribiendo en lugar de esperar a que recargue la página.

Toda escritura pasa por una sola puerta

Un documento puede cambiarlo alguien que escribe en él y también un programa que llama a la API, y antes esos dos caminos podían escribir en la misma página de forma independiente. Ya no pueden. Una escritura llegada de la API se reenvía a la misma sesión que sostiene el documento vivo, donde se aplica como una única transacción junto a las ediciones en curso, de modo que hay un solo orden de sucesos y no dos escritores con opiniones distintas sobre lo que dice la página. Los identificadores de los bloques se conservan al volver a escribir el documento, porque los comentarios están anclados a ellos y una reconciliación que acuñara identificadores nuevos dejaría a cada comentario apuntando a la nada. Y cuando el conjunto de bloques resultante es idéntico al ya guardado, no se escribe nada en absoluto.

El único transporte al que no llega una clave de máquina

Una clave de API personal funciona con REST, con GraphQL, con el socket de suscripciones de GraphQL y con MCP. No funciona con el socket de colaboración, y eso es deliberado. Cada cambio hecho en colaboración lleva el sello de la persona que lo hizo, y esos sellos se convierten en la autoría registrada en el historial de la página. Un principal de máquina que editara ahí escribiría un autor que ninguna persona escribió, y deshacer eso más adelante significa reescribir la historia y no borrar una fila. La línea no separa websockets de HTTP: separa según si el transporte escribe historial con autoría. La regla la impone la forma del código y no la memoria, ya que aceptar una clave exige pasar deliberadamente a otra llamada de autenticación, y una prueba falla cuando un transporte lo hace.

Un espacio de trabajo en su propia dirección

Cada espacio de trabajo es un inquilino con su propio subdominio desde el momento en que se crea, y el inquilino se resuelve a partir de la dirección por la que llegó la petición. En qué inquilino estás queda decidido, por tanto, antes de que se lea ninguno de tus datos, y no mediante un filtro añadido después que alguien pudiera olvidar. Por debajo, es la propia base de datos la que impone la frontera mediante seguridad a nivel de fila: cada petición toma prestada una conexión, le estampa la identidad de quien llama, y el conjunto de conexiones borra ese estado al devolverla, de modo que la identidad de una petición no puede filtrarse a las consultas de la siguiente.

Reclamar un dominio no es lo mismo que demostrarlo

Un espacio de trabajo en un plan Enterprise puede servir sus páginas desde un dominio propio. Reclamar un dominio y servir desde él son adrede dos pasos distintos: el dominio se guarda sin verificar, y el resolvedor lo ignora por completo hasta que aparece un registro de verificación en el DNS. Cualquiera puede escribir la dirección de otra empresa en un formulario. Solo quien controla ese dominio puede publicar el registro que lo pone en marcha.

Todas las versiones que ha tenido la página

Clepit guarda revisiones y no un único estado actual. Se toma una instantánea de forma automática mientras la gente trabaja, contenida para que escribir normalmente no produzca cientos de ellas: se escribe una nueva en cuanto pasan diez minutos o cambian diez bloques, lo que ocurra antes. Restaurar es una sola transacción: se aplica la instantánea antigua, se reconcilian los bloques y la propia restauración se escribe como una revisión nueva, de modo que volver atrás queda registrado y no deshecho en silencio. La reconciliación conserva a propósito los identificadores de bloque del origen, porque los comentarios están anclados a bloques y restaurar una página con identificadores nuevos dejaría sin ancla a cada comentario que hubiera en ella.

Volver a encontrarlo

La búsqueda se ejecuta sobre una proyección de las páginas, y la consulta pasa por el analizador de búsqueda web del propio Postgres en lugar de armarse en SQL a mano, de modo que alguien puede escribir comillas y signos menos sin que nada de eso constituya una superficie de inyección. Lo que importa en un espacio compartido, sin embargo, es dónde está la comprobación de permisos. La búsqueda une la tabla de páginas, y la seguridad a nivel de fila de esa tabla se aplica a la unión, así que los resultados ya están restringidos a las páginas que quien pregunta puede ver. Los filtros (una rama del árbol de páginas, quién la revisó por última vez, cuándo se editó por última vez) se añaden encima como condiciones adicionales. Todos ellos estrechan; ninguno puede ampliar, porque todos se sitúan detrás de la misma comprobación.

Publicar congela, compartir no

Son dos cosas distintas y Clepit las trata de forma distinta a propósito. Publicar una página congela el documento actual como una revisión, apunta la página hacia ella y la hace pública: lo que un visitante lee en clepit.space, en una dirección del estilo acme.clepit.space/handbook, es esa revisión congelada y no las ediciones hechas después. Despublicar borra esos punteros pero conserva la dirección pública, de modo que volver a publicar más adelante regresa a la misma URL en vez de romper todos los enlaces que apuntaban ahí. Un enlace compartido es lo contrario: sirve el documento vivo, así que lo que ve quien lo recibe cambia a medida que cambia la página.

Un enlace que puedes retirar

Un enlace compartido es un testigo que puedes revocar, y al acuñarlo se le puede poner una caducidad. Solo se guarda un resumen criptográfico del testigo, de modo que el enlace se muestra una vez al crearlo y después no puede recuperarse de la base de datos, ni por nosotros ni por quien llegue hasta ella. Estos enlaces conceden lectura, no comentario: un comentario necesita un autor, y quien tiene un enlace no lo es.

Iniciar sesión desde tu propio directorio

Un espacio de trabajo puede entregar la autenticación a su propio proveedor de identidad: OpenID Connect en el plan Business, SAML en Enterprise, y junto a él SCIM para sincronizar el directorio. SCIM cubre el recurso de usuario que Okta y Entra manejan de verdad, y se aparta a propósito de la lectura obvia del estándar en un punto: un borrado desactiva al miembro en lugar de eliminarlo. La especificación lo permite, y la alternativa es una sincronización de directorio capaz de destruir el contenido de un espacio de trabajo por haber sacado a alguien de un grupo.

Cuatro maneras de hablar con él

REST cubre cuarenta y cuatro operaciones bajo /v1, descritas por un documento OpenAPI generado a partir de las propias rutas y no escrito junto a ellas, y la integración continua compara esa salida con la copia versionada, de modo que un cambio de ruta que se salte el registro no puede colarse en silencio. GraphQL cubre el modelo de la aplicación y lleva las suscripciones por su propio socket. El tiempo real es un proceso aparte, y por eso reiniciar la pasarela no se lleva por delante la superficie de peticiones, y autoriza por socket en lugar de por sala: para cada suceso, todas las conexiones del inquilino se evalúan en una única comprobación agrupada y solo lo reciben aquellas a las que se permite verlo. MCP expone esas mismas operaciones a los agentes de IA como herramientas, y ninguna herramienta se fía de un identificador venido de quien llama para decidir en qué espacio de trabajo actúa; las escrituras pasan por los mismos servicios que usa la interfaz, así que las comprobaciones de permisos y el rastro de auditoría son los mismos.

Para quién es

Equipos que necesitan un editor bajo su control, y desarrolladores que integran contenido estructurado en su propio producto.

Visitar Clepit: clepit.com