Resumen

signed by Lollyoverview.htmlHTMLAI generatedgenerated by ClaudeCompruébalo tú mismoGet the signed filepixels, not shapes12 KB

Icono de Lolly - Piruleta grande verde y blanca

Este documento recoge el propósito, la estructura y las decisiones arquitectónicas de la plataforma Lolly. Refleja tanto la visión del producto como el estado actual del código.

Estado: Lolly es un prototipo interno en un piloto cerrado que aún no ha concluido. El motor es determinista e internamente consistente, pero el producto está en fase temprana - SUSE es el cliente número uno - y sus motores de criptografía y análisis de archivos están actualmente sometidos al estricto endurecimiento de infraestructura de SUSE, preparándose para escala empresarial (se nos da muy bien esto). Lee la arquitectura de abajo como intención de diseño en prueba, no como un producto terminado y certificado. Ver Adopción y Gobernanza para saber cómo se gestiona y mide el piloto.

Cómo leer esta página. Contiene dos tipos de material, en orden. La primera mitad es por qué existe esto: el problema, el posicionamiento y el ciclo de vida por el que pasa un solo activo. A partir de El panorama general en adelante es cómo encajan las capas: el documento de arquitectura para colaboradores, que cubre la separación motor/shell/pack, la disposición del repositorio, los objetivos de entrega y los compromisos que limitan cada cambio a la plataforma. Si estás aquí para cambiar el código en lugar de entender el producto, empieza por el panorama general.

Dos documentos complementarios profundizan más que esta página. engine/README.md en el repositorio es el mapa módulo a módulo del motor, con una tabla generada de cada módulo y lo que analiza o escribe. Modelo de amenazas y límites de confianza es la misma arquitectura leída como límites de confianza, y es la página adecuada para cualquier pregunta sobre qué trata el motor como no confiable.


Por qué existe esto

Los equipos se enfrentan a un problema recurrente: trabajo creativo y de contenido repetible que es demasiado predecible para justificar manos expertas cada vez, pero demasiado sensible a la calidad para delegarlo sin barandillas. El resultado es o bien un rendimiento lento (cuello de botella del especialista), inconsistencia (gente usando la herramienta que tenga a mano) o dependencia de proveedor (un DAM SaaS que controla tus plantillas).

Esta plataforma es la respuesta directa:

Contenido y creatividad programática a escala - generación de activos sin esfuerzo humano, con las reglas bajo control central, para empleados, proveedores y socios.

Lolly no es donde se inventa un sistema de diseño - es donde se produce. Piénsalo como una máquina expendedora de diseño: haces una selección, obtienes un resultado. Cada vez. El engine busca la mayor calidad que cada formato puede producir en el hardware que tienes delante, y el mismo engine genera el mismo archivo en cada superficie a la que se despliega.

El resultado es abundancia: cada evento tiene la señalización correcta, cada alerta CVE coincide con el estilo corporativo, cada etiqueta se imprime limpia, cada firma de correo está actualizada - todo sin un ticket de diseño. La plataforma gestiona la creatividad operacionalizada recurrente. Deliberadamente no es una herramienta creativa a medida - los diseñadores siguen siendo dueños del trabajo insignia.

Innova de forma probabilística, escala de forma determinista

Todo debate sobre la IA en un pipeline creativo se estanca en la misma pregunta: ¿qué parte de esto es trabajo de la máquina? Es una pregunta antigua con una respuesta ya asentada. Los escribas e iluminadores ya trabajaban entre dos instrumentos - el boceto libre, donde nada estaba fijado y todo podía probarse, y la imprenta, intimidante precisamente porque comprometía. Los bocetos eran donde ocurría el arte. La imprenta era el modo en que llegaba a cualquiera. Nadie confundía ambas cosas, y las dos siguieron avanzando - nuevas tintas, nuevos tipos, nuevas prensas - cada una mejorando en armonía con el oficio y la intención a la que servía.

Lolly traza la misma línea. Explora de forma probabilística: un modelo, un diseñador, una idea aproximada, un prompt que va a algún sitio que nadie planeó. Luego escala de forma determinista - lo que llega a diez mil resultados es una herramienta, y una herramienta se renderiza igual cada vez a partir de entradas que puedes leer. La exploración permanece libre porque nada aguas abajo depende de que salga igual dos veces. El resultado se gana la confianza porque no es una conjetura. Llevar la experimentación con IA a resultados predecibles y reproducibles no es una disciplina nueva; es la misma división del trabajo que hizo que el trabajo impreso mereciera confianza desde un principio.

Confía en el proceso creativo, escala con rigor.

Frente a las alternativas

Capability Lollyconstraint-first Penpotopen design CanvaAffinity
Cavalry
Adobedesktop pro Brand DAMFrontify
Bynder
Cloudinarymedia pipeline Figmaonline pro Render APIsBannerbear
Placid
Creatomate
Overall completenessunweighted mean - weight rows for your own context · columns are sorted by this row 84 70 57 48 41 41 41 34
Production maturity & track recordCanva, Adobe, Figma, Bynder/Frontify: a decade-plus at massive scale. Render APIs: years in production pipelines. Penpot: shipping, large community, younger at enterprise scale. Lolly: closed pilot, security hardening underway, no public case studies. Cloudinary: 2012, enterprise media infrastructure at global scale.
25 75 100 100 100 100 100 75
Mass generation from data (CSV / API)Lolly: batch grid + CLI, one file per row. Canva: Bulk Create + Autofill API - real, but Enterprise-gated, async, text/image fields only; Affinity Publisher adds desktop data merge. Adobe: InDesign data merge and scripting. Figma: Buzz fills templates from CSV or XLSX, free in beta (Aug 2026) - cloud- and account-gated, 50. Penpot: open API/MCP, not purpose-built. Render APIs: this is their entire product - account- and cloud-gated, so 75 under the method rule. DAM: Studio-style batch create and resize. Cloudinary: URL-driven overlays and named transforms derive variants at scale - account-gated, 75.
100 50 50 50 75 75 50 75
Offline & air-gap operationLolly: static deploy, no server in the render path, MDM/air-gap. The Canva column is scored on its best family member: Affinity (free since Oct 2025) runs offline as a desktop suite once a verified account activates it - 75, the same deduction Adobe takes. Canva's own Offline (2026) still edits pre-synced designs only, per device, in a 14-day window. Adobe: desktop apps run offline; licensing phones home. Figma: cached-file viewing and limited editing. Penpot: self-host on your infra behind a firewall (server required). Cloud APIs and DAM: none.
100 75 75 75 0 0 25 0
On-device rendering - data never leavesLolly: renders and converts in-browser or CLI, locally; zero upload. Adobe: local desktop rendering, but cloud services and telemetry in the suite. Figma: canvas renders locally, files live in Figma's cloud. Penpot: 90 - rendering happens in the browser and the save target is a server that can be your own sovereign private cloud, even your own laptop, with private export throughout; only the server hop separates it from Lolly. Canva itself is server-side by design; the column's 75 is Affinity - local desktop rendering, account activation and telemetry, the same shape as Adobe. Render APIs, DAM: server-side by design.
100 90 75 75 0 0 25 0
Hard brand constraints (structural)Lolly: rules compiled into template code - off-brand output is impossible, not just discouraged. Canva: element locks - permission-based, admin-set and static: no template logic such as conditional logo switching or responsive recomposition at fill time, and Canva AI does not yet respect Brand Controls - 50. Render APIs: templates are fixed (only declared fields vary) but no governance layer. DAM: locked templates with restrictions. Figma: Buzz templates hold locked guidelines at fill time; the design surface stays review-enforced - 50. Penpot: tokens and systems enforced by review, not runtime. Adobe: libraries, little enforcement. Cloudinary: presets and Enterprise-gated transformation templates fix operations, not brand layout - 50.
100 50 50 25 75 50 50 75
C2PA provenance, signed at creationAdobe: the broadest shipped implementation (Photoshop, Lightroom, Premiere, Firefly) - signing happens locally in the desktop apps and in the cloud for the Content Authenticity web app, and nothing signs without an Adobe account and an Adobe-provisioned identity, so it is account-gated end to end: 75 under the method rule. Lolly: on-device key generation, offline signing, plus pixel imprint - no account anywhere; the on-device key reads as unverified in stock validators (the interim trust list froze Jan 2026) until an identity or an organization's own CA vouches for it, and the stack is pilot-stage and unaudited, so 75. Penpot: 50 via the official Lolly Export plugin - the same on-device engine signing Lolly uses, opt-in rather than default (and disclosed plainly: it is Lolly's own plugin). No evidence of C2PA writing in Canva, Figma, render APIs or DAM as of Aug 2026. Cloudinary: 50 - signs images on delivery (fl_c2pa, CAI member since 2020), attesting delivery by Cloudinary rather than creation by you.
75 50 0 75 0 50 0 0
CLI, pipeline & AI-agent automationLolly: CLI, TUI, MCP server, URL mode - one engine everywhere. Render APIs: API-first, webhooks, integrations - account- and cloud-gated, so 75 under the method rule. Penpot: open API, plugins, official MCP server. Canva: Connect API - Enterprise-gated, async, rate-limited. Adobe: UXP/ExtendScript plus Firefly APIs. Figma: strong REST/plugin API, no render pipeline. DAM: asset-management APIs. Cloudinary: API-first media pipeline - account-gated, 75.
100 75 50 50 50 75 50 75
Live collaboration (real-time co-editing)The capability that trades most directly against offline. Figma: the scale benchmark - 200 simultaneous editors, up to 500 people in a file - account and cloud required. Canva: mature real-time editing across the product, same precondition. Penpot: real-time multiplayer with live cursors; self-hosting lifts the vendor-account precondition, but a server is still required. Lolly: pairwise P2P shipped - an invite/accept ceremony (QR, link or code), LAN-first, zero server, no account, works fully air-gapped - no large rooms, so Partial; the only column that collaborates with no internet at all. Adobe: Live Co-Editing in beta, cloud documents only. Render APIs: no editing surface. DAM: comments and approvals, not canvas co-editing. Cloudinary: DAM comments and workflows, no canvas co-editing.
50 75 75 25 25 25 75 0
No design skill requiredCanva: the category benchmark for ease. DAM: fill a locked template. Lolly: fill in fields - but someone technical must author tools first (the cold-start cost sits with builders, not producers). Render APIs: swaps design skill for developer skill. Adobe, Figma, Penpot: professional tools. Cloudinary: the media library is easy; transformations are developer territory.
100 25 100 25 100 50 25 50
Open source, self-hosted, no lock-inPenpot: MPL-licensed, 51k+ stars, self-host via Docker/K8s - fully verifiable today. Lolly: MPL-2.0, the repository is public (github.com/lolly-tools/lolly), OBS builds, no contributor agreement - and it is young: months in public, no external audit, a community still forming, with SUSE maintaining it as a user of its own systems. 75 while youth is the honest deduction. Everything else is proprietary SaaS or proprietary desktop.
75 100 0 0 0 0 0 0
Cost at production scaleLolly and Penpot: zero marginal cost on your own hardware. Render APIs: metered - roughly $0.005–0.049 per image, credits often expiring monthly. Canva/Figma: per-seat; Canva's automation needs Enterprise, though Affinity itself is free since Oct 2025. Adobe: premium per-seat suite. DAM: sales-led enterprise quotes, MAU or seat models. Cloudinary: credit-metered across transforms, storage and bandwidth - 25.
100 100 50 25 25 25 50 25
Annual medium enterprise spendIndicative list-price arithmetic for a medium enterprise - think 500-5000 people - August 2026: a guess range, not a quote; deals vary and the seat mix dominates. Ring = how much of the board's largest annual spend (US$500k) you keep; the number in the ring is each range's upper bound. Canva (US$75k-400k; Affinity free since Oct 2025 pulls the design-seat share down), Adobe (US$100k-500k) and Figma (US$30k-250k) assume the realistic creative-seat share of an organisation this size - tens to hundreds of seats, not a licence for every employee. Render APIs price by usage (US$5k-60k). DAM is quote-only, commonly US$50k-250k and up. Penpot is hand-set at 99: "your server" can be your own laptop - a small technical hurdle at well under 1% of an Adobe-scale spend. Lolly: US$0 by licence - the apps ship free, run offline and keep working in perpetuity; works on devices immediately, config optional; hosting an instance is an organisation's choice, not a cost of entry. Cloudinary: US$30k-150k, credit-based; enterprise contracts commonly sit near US$82k.
$0 $0 $400k $500k $250k+ $150k $250k $60k

Integridad de capacidades entre las herramientas creativas actuales, investigado en agosto de 2026. Puntuación: 0 ausente, 25 nivel workaround, 50 real pero limitado o parcial, 75 sólido con salvedades, 100 competencia central.

signed by Lollypositioning-comparison.htmlHTMLAI generatedgenerated by ClaudeCompruébalo tú mismoGet the signed filepixels, not shapes38 KB

La brecha es clara: nada de lo que existe hoy ofrece un resultado basado en restricciones, capaz de funcionar sin conexión, de baja exigencia técnica y accesible internamente. Lolly incluso incluye un lienzo abierto - Design - donde los colores, la tipografía y los assets se ajustan a los globales de marca, de modo que la composición libre sigue partiendo de restricciones. Lo que no es es una suite de diseño sin restricciones: los diseñadores siguen usando Illustrator y Figma para trabajo insignia a medida. Con esta herramienta pueden ensamblarse permutaciones.

Cada herramienta de la biblioteca como una tarjeta, agrupada por categoría, para que un productor elija una y empiecesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file281 paths~38k nodes443 groups6 images2269 KBCada herramienta de la biblioteca como una tarjeta, agrupada por categoría, para que un productor elija una y empiecesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file281 paths~38k nodes443 groups6 images2270 KB

Úsala para: Generación rápida de assets creativos operacionalizados - tarjetas de evento, credenciales de nombre, firmas, alertas CVE, códigos QR, tarjetas sociales, etiquetas de envío, informes estructurados.

No la uses para: Contenido insignia a medida.


El ciclo de vida de una campaña

La forma más clara de ver qué es Lolly no es una lista de funciones - es seguir un único asset mientras pasa de mano en mano. Observa cómo una tarjeta de campaña localizada se mueve por la organización:

  1. El creativo fija las reglas. Un diseñador crea la plantilla base en la herramienta Design, codificando la tipografía y las variables de color de la marca. No está haciendo una tarjeta - está haciendo el trabajo fundacional una vez para no tener que volver a localizarlo a mano nunca más.
  2. El desarrollador la escala. Esa misma plantilla se conecta a un pipeline nocturno mediante la CLI, de modo que un gráfico nuevo o una nueva variante de idioma se genera automáticamente - sin que nadie vuelva a abrir el archivo.
  3. El productor simplemente la usa. Un representante de ventas, sin conexión en un avión, abre esa misma herramienta y genera una presentación perfectamente alineada con la marca para una reunión con un cliente. Sin conocimientos de diseño, sin red, sin espera.

El «gráfico nuevo» del paso dos es un render como este, producido a partir de una cadena de datos y un puñado de parámetros sin que nadie abra un archivo de diseño:

Un gráfico de área apilada con título, sus tres series en bandas dentro de una paleta fría, con ejes, leyenda y título colocados todos por la plantilla en lugar de a manosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file15 paths~1.3k nodes4 groups21 KBUn gráfico de área apilada con título, sus tres series en bandas dentro de una paleta fría, con ejes, leyenda y título colocados todos por la plantilla en lugar de a manosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file15 paths~1.3k nodes4 groups21 KB

No se trata de que Lolly sea buena para diseñadores y buena para desarrolladores y buena para ventas, cada una en un vacío. Es una carrera de relevos: el trabajo inicial del creativo lo escala el desarrollador, lo que a su vez capacita al productor. La experiencia sin esfuerzo para el representante sin conocimientos técnicos en el avión solo es posible gracias al rigor que fijó el diseñador y desplegó el desarrollador.

Ese es el multiplicador de fuerza. Lolly no es un cajón de herramientas separadas para roles separados - es un único ciclo de vida de assets determinista que toca cada rol, y cada mano por la que pasa multiplica el valor de la anterior.


Una aprobación, diez mil assets

Como la aprobación vive en la herramienta y no en el archivo (ver Cómo se compara Lolly), la escala deja de ser un problema de revisión. Aprueba una herramienta de tarjeta social localizada una vez, luego genera 10.000 assets en 12 idiomas a partir de una hoja de cálculo - y ninguno de ellos necesita una nueva revisión de cumplimiento por parte de legal o de marca, porque la plantilla de la que provienen todos ya fue aprobada.

La misma herramienta determinista alcanza esa escala de tres formas, todas produciendo un resultado idéntico y preaprobado:

El modo Batch en una instalación recién hecha: una fila vacía esperando una herramienta, con toda la superficie tipo hoja de cálculo y su botón Renderizar ya en su sitio antes de que lleguen datossigned by Lollyvector SVGCompruébalo tú mismoGet the signed file348 paths~77k nodes537 groups7 images3100 KBEl modo Batch en una instalación recién hecha: una fila vacía esperando una herramienta, con toda la superficie tipo hoja de cálculo y su botón Renderizar ya en su sitio antes de que lleguen datossigned by Lollyvector SVGCompruébalo tú mismoGet the signed file348 paths~77k nodes544 groups7 images3103 KB

Un conjunto de restricciones de marca, fijado una sola vez por un diseñador; tres rutas hacia el mismo resultado idéntico y preaprobado - y la ruta de la máquina escala más lejos que ninguna otra, porque nunca se cansa mientras entran los archivos.


El panorama general: cómo encajan las capas

Todo lo que sigue a partir de aquí es arquitectura. El diagrama es el sistema completo en una sola vista: las herramientas son datos arriba, el motor en el medio no sabe nada de ninguna plataforma, los shells debajo de él implementan un único contrato, y los catálogos aportan el contenido.

                ┌─────────────────────────────────────────────┐
                │              Tools (data, not code)         │
                │   tool.json + template.html + hooks.js?     │
                └─────────────────────────────────────────────┘
                                    ▲
                                    │ talks to via Capability Bridge v1
                                    ▼
                ┌─────────────────────────────────────────────┐
                │                  Engine                     │
                │   loader · validator · runtime · template   │
                │   inputs · url-mode                         │
                │   PLATFORM AGNOSTIC. Knows nothing of DOM,  │
                │   filesystem, or You.                       │
                └─────────────────────────────────────────────┘
                                    ▲
                                    │ implements HostV1
                                    ▼
        ┌──────────────┬──────────────┬──────────────┬──────────────┐
        │  Web Shell   │ Tauri Desktop│ Tauri Mobile │  CLI Shell   │
        │   (PWA)      │              │              │              │
        └──────────────┴──────────────┴──────────────┴──────────────┘
                                    ▲
                                    │ fetches from
                                    ▼
                ┌─────────────────────────────────────────────┐
                │              Catalogs                       │
                │   catalog/tools/index.json + tool dirs      │
                │   catalog/assets/index.json + asset files   │
                └─────────────────────────────────────────────┘

Estructura del repositorio

El contenido se monta como paquetes: community/, docs/, cada shells/, tanto services/ como brands/suse son cada uno su propio repositorio, incorporado como submódulo git de este. El padre posee engine/, schemas/, scripts/, tests/, api/, brands/lolly-start/ y profiles.json. Ver Guía de compilación » Obtener el código fuente para el comando de checkout y el flujo de trabajo entre repositorios.

lolly/
├── engine/           # Platform-agnostic core. Open source (MPL-2.0).
│   └── src/
│       ├── index.ts          # public surface - loader, runtime, template, inputs, url-mode
│       ├── loader.ts         # fetches and validates tool files
│       ├── runtime.ts        # orchestrates the 5-step lifecycle
│       ├── template.ts       # Handlebars hydration + annotateTemplate
│       ├── inputs.ts         # manifest → runtime input model
│       ├── url-mode.ts       # URL ↔ input state round-trip
│       ├── validate.ts       # JSON Schema validation of manifests
│       ├── compose.ts        # resolve nested tool renders (composes)
│       ├── embed.ts          # parse portable lolly.tools embed URLs
│       └── bridge/
│           └── host-v1.ts    # type re-export of the @lolly-tools/core contract
│
├── shells/
│   ├── web/          # PWA - hosted online; primary distribution
│   │   └── src/
│   │       ├── main.ts           # boot, routing
│   │       ├── theme.ts          # theme apply/persist (FOUC prevention)
│   │       ├── bridge/           # web implementations of HostV1 APIs
│   │       │   ├── index.ts      # compose all bridge pieces
│   │       │   ├── db.ts         # IndexedDB setup
│   │       │   ├── state.ts      # host.state - saved edits
│   │       │   ├── profile.ts    # host.profile - user details
│   │       │   ├── assets.ts     # host.assets - catalog + user uploads
│   │       │   ├── clipboard.ts  # host.clipboard
│   │       │   ├── export.ts     # host.export - rasterise/serialize
│   │       │   ├── net.ts        # host.net - allowlisted fetch
│   │       │   └── media.ts      # host.media - live camera frames (onFrame)
│   │       ├── catalog/
│   │       │   └── sync.ts       # boot-time catalog sync + offline cache
│   │       ├── styles/           # app-wide CSS (app.css, picker.css, tokens.css)
│   │       └── views/
│   │           ├── gallery.ts    # tool library listing + saved-state cards
│   │           ├── tool.ts       # mounts one tool (inputs + canvas + actions)
│   │           ├── picker.ts     # asset picker UI (invoked by host.assets)
│   │           ├── profile.ts    # user details editor
│   │           ├── projects.ts   # /p - folders of saved sessions (nested; folder/selection export)
│   │           └── free-canvas.ts # free-canvas editor overlay for render.layout:"editor" tools
│   │
│   ├── cli/          # Node.js CLI - same engine, headless jsdom
│   │   ├── bin/lolly.ts
│   │   └── src/
│   │       ├── run.ts    # loadTool → createRuntime → export → write file
│   │       └── bridge.ts # CLI implementation of HostV1
│   │
│   ├── tui/          # Interactive terminal shell (Ink) - reuses the CLI bridge
│   │   └── src/
│   │       ├── main.tsx  # full-screen app: Gallery / Projects / Profile / ToolView
│   │       └── bridge.ts # CLI bridge + on-disk state under ~/.lolly
│   │
│   ├── tauri-desktop/ # downloadable desktop app
│   └── tauri-mobile/  # iOS/Android app
│
├── tools/            # profile VIEW (gitignored) - data, not code. Merged from packs:
│                     #   community/ (public, brand-agnostic, MPL) + brands/<active>/tools (brand-owned).
│                     #   A SELECTION follows - the mounted set depends on the profile.
│   ├── qr-code/
│   ├── quotes/
│   ├── email-signature/
│   ├── snippet/
│   ├── countdown-timer/
│   ├── color-palette/
│   ├── color-block/           # typed/heterogeneous blocks (addMenu discriminator)
│   ├── dynamic-layout/
│   ├── tool-logo/         # "Logo" - auto-switching brand logo
│   ├── street-map/        # offline vector city-block maps
│   ├── url-shot/          # "URL Screenshot" (capture capability)
│   ├── strip-data/        # on-device metadata strip - JPEG/PNG/SVG/PDF (file in → clean file out)
│   ├── compress-pdf/      # on-device PDF compressor - recompresses images (file in → smaller file out)
│   ├── brand-lockup/      # "Brand Lockup" - SUSE logo lockups; HarfBuzz text-to-path (wasm)
│   ├── chart-creator/     # SVG charts from structured data
│   ├── filter/            # photo effects in one tool - halftone/scanline/posterize/voronoi (vector), duotone/pixel-stretch/imperfections (raster)
│   ├── meeting-planner/   # global timezone meeting scheduler
│   ├── calendar-ics/      # event → .ics calendar file plus a card
│   ├── digi-ad/           # "Animated Ad" - looping banner from scenes
│   ├── event-name-badge/  # conference badges - composes qr-code as an SVG
│   ├── wayfinding-signage/ # event signage; directions blocks auto-fit label text
│   ├── text-helper/       # on-device text workbench (format/decode/hash/de-identify)
│   ├── design/     # "Design" - freeform WYSIWYG editor canvas (render.layout: editor)
│   ├── multi-page-pdf/    # multi-page PDF document - cover, flowing content blocks, back page
│   ├── diagram-builder/   # org / layercake / process / cycle / pyramid diagrams
│   ├── logo-wall/         # many logos → auto-packed grid
│   ├── logo-lockup-partner/ # SUSE + partner co-brand lockup
│   ├── icon/          # favicon .ico / png / svg from text + colours
│   ├── lottie-digi-ad/    # animated Lottie ad banners
│   └── pose-geeko/        # pose the SUSE Geeko mascot - print-ready stills
│
├── catalog/
│   ├── tools/index.json        # tool registry
│   └── assets/
│       ├── index.json          # asset registry
│       └── suse/...            # logo, palette, etc.
│
├── schemas/          # JSON Schema for tool.json, asset entries, AssetRef
├── scripts/          # build-catalog-index.ts, checksum-assets.ts, validate-catalog.ts
├── tests/            # engine tests
└── docs/             # this file + authoring guides + positioning

Modelo de distribución de la plataforma

La plataforma funciona en varias superficies - PWA web, Tauri de escritorio/móvil, la CLI programable y la TUI interactiva. Todas usan el mismo motor y los mismos archivos de herramienta.

Web (PWA) - distribución principal

Alojada en una URL controlada por SUSE. Funciona sin conexión una vez que el service worker ha almacenado en caché las herramientas y los assets. Aquí es donde la mayoría de empleados, proveedores y socios usarán la plataforma. No requiere cuenta - el estado se almacena en IndexedDB por dispositivo.

El shell web es responsivo a partir de un único diseño. En escritorio, una herramienta es una barra lateral de controles redimensionable junto a un escenario de vista previa con navegación de lienzo nativa de trackpad (Cmd/Ctrl-rueda o pellizco para hacer zoom sobre el cursor, arrastre con Espacio o botón central para desplazar, teclas 0/1/+/ y un HUD de Ajustar/%). En móvil (≤640px) los controles se convierten en una hoja anclada arriba con una pestaña de arrastre que encaja en asomo/mitad/completo (tocar alterna) sobre una vista previa estática a pantalla completa, y un botón flotante Render abre los controles de Export en una ventana emergente inferior. El tacto permite pellizco para zoom y arrastre para desplazar en la vista previa. La ruta de render y los controles de exportación son idénticos en ambos - solo el chrome se reorganiza.

La vista dividida de escritorio - controles generados a partir del manifiesto a la izquierda, el lienzo en vivo a la derechasigned by Lollyvector SVGCompruébalo tú mismoGet the signed file5 paths989 nodes11 groups14 KBLa vista dividida de escritorio - controles generados a partir del manifiesto a la izquierda, el lienzo en vivo a la derechasigned by Lollyvector SVGCompruébalo tú mismoGet the signed file5 paths989 nodes11 groups14 KB

La misma herramienta con ancho de teléfono, sin un segundo diseño que mantener: los controles se convierten en una hoja arriba, la vista previa ocupa toda la pantalla y la píldora de render flota sobre ella.

Un audiograma en una pantalla de 430px de ancho - la hoja de controles arriba, la ilustración cuadrada terminada abajo y la píldora de renderizado flotantesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file47 paths~1.9k nodes84 groups1 image212 KBUn audiograma en una pantalla de 430px de ancho - la hoja de controles arriba, la ilustración cuadrada terminada abajo y la píldora de renderizado flotantesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file47 paths~1.9k nodes84 groups1 image211 KB

Modo lote (/pro). El shell web también incluye una cuadrícula de lote tipo hoja de cálculo (shells/web/src/pro/) que renderiza muchas filas a la vez en una o varias herramientas. Ofrece ida y vuelta CSV/TSV más pegado tipo hoja de cálculo, plantilla/formato/tamaño/unidad/dpi por fila, un panel lateral editor de bloques con vista previa en vivo, columnas de exportación colapsables, una barra de etiquetas de «relevancia» por fila, reordenación de filas mediante asa de arrastre a la izquierda, confirmación de borrado en dos pasos, sesiones de lote guardadas y una descarga en .zip. Esta es la superficie de uno a muchos detrás del posicionamiento de «generación masiva de contenido».

Tauri de escritorio / móvil

App nativa empaquetada (huella pequeña gracias a Tauri). Ofrece disponibilidad sin conexión completa, acceso al sistema de archivos para herramientas que dependen de la CLI (PDF Smasher, Font Outliner) y acceso a la cámara. Programado para una mejora de herramientas a mediados de 2026.

CLI

lolly <tool-id> [--input=value ...] --output=file.png

Los usuarios de escritorio pueden invocar muchas herramientas desde la terminal. El shell de la CLI carga el mismo motor, crea un DOM de jsdom, ejecuta la misma ruta de render y escribe el archivo. El modo URL es el transporte - la CLI no es una implementación separada. Esto garantiza que las salidas de la CLI y de la GUI sean idénticas.

lolly qr-code --url=https://suse.com --output=qr.svg
lolly quotes --quote="Ship it." --output=quote.png
lolly                        # lists available tools
lolly qr-code                # lists inputs for that tool

TUI

npm run tui

La contrapartida interactiva de la CLI: una app de terminal a pantalla completa y centrada en el teclado (construida sobre Ink) para explorar herramientas, rellenar entradas, guardar proyectos y exportar - todo sin una GUI. Su bridge de host reutiliza la implementación de la CLI para los formatos sin DOM (SVG/EMF/EPS/HTML + texto/datos), y añade estado en disco bajo ~/.lolly más una vista previa en línea opcional. Más allá de eso tiene un nivel de render en navegador: un Chromium headless acotado (el mismo que instala el servidor MCP) que produce ráster/PDF/vídeo y captura de URL en vivo a demanda - impulsando una copia compilada del shell web para que el resultado sea idéntico, y arrancando solo cuando exportas por primera vez un formato así. De modo que url-shot (con recorte + recoloreado + PDF/SVG vectorial) y todas las herramientas de ráster/pdf también funcionan en la terminal. Ver la guía de TUI.

Sea cual sea la superficie en la que estés, la pestaña Capabilities del panel es el mapa completo de lo que la plataforma declara que puede hacer, agrupado y legible sin abrir ni una sola herramienta.


Categorías de herramientas

Las herramientas están etiquetadas con una category en su manifiesto para agruparlas en la galería.

Las filas se listan en el orden de sección de la galería. La sección utility siempre se muestra al final en la galería (después de cualquier otra categoría, incluidas las futuras) - es el cajón «Utilidades sin conexión» en el dispositivo.

CategoríaEjemplosPrevisto
everyoneQR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence Studio, RecordEmployee Image Stationery
designerBrand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, Multi-Page PDFFont Outliner
eventMeeting Planner, Event Name Badge, Wayfinding Signage, Calendar ICS, Booth StudioEvent Stationery, Bulk Name Badges, Room Agenda Cards
product-CVE Alert, Product Release Announcement, Blog OG Image
utilityStrip Hidden Data, Text Helper, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL ScreenshotUnit/format converters, more on-device privacy utilities

Esas celdas son ejemplos, no inventarios. Qué herramientas existen es una propiedad del perfil que hayas montado, no de esta página: un paquete de marca añade las suyas propias, y puede excluir una herramienta comunitaria que prefiera no distribuir. catalog/tools/index.json - generado a partir de los manifiestos, y el registro que la galería realmente lee - es la lista autorizada; para contar lo que monta un perfil, cuenta los manifiestos (ls community//tool.json brands//tools/*/tool.json) en lugar de confiar en un número escrito aquí. (Un id de herramienta presente en dos paquetes se monta una sola vez, desde el paquete ganador.)

Las herramientas también se clasifican por estado: official (aprobada por la marca, sin marca de agua), community (contribución externa), experimental (exportaciones con marca de agua). La mayor parte de la biblioteca es official; los estudios más nuevos y las herramientas de captura tienden a estar en community o experimental mientras se estabilizan. Cada superficie muestra la insignia, así que quien lee sabe qué está tomando antes de abrirlo - y, como las celdas de categoría de arriba, la pertenencia por estado cambia demasiado rápido para enumerarla aquí. Consúltala en la galería o en el índice generado.

Design es la primera herramienta construida sobre el modo de lienzo libre render.layout: "editor" - una superficie sin cromado, de manipulación directa, donde arrastras, redimensionas, rotas y ajustas cajas de texto, formas e imágenes, y luego exportas por la misma ruta de renderizado que cualquier otra herramienta.

Strip Hidden Data es la primera utilidad en el dispositivo (privacy: "on-device"): una herramienta de transformación de contenido que toma un archivo que aportas, lo procesa por completo en el navegador y devuelve una copia limpia - nunca se sube, nunca lleva marca de agua, no se estampa procedencia. Text Helper es la segunda - un banco de trabajo en el dispositivo para las tareas cotidianas de pegar-en-un-sitio-web (formato JSON, decodificación JWT, Base64, codificación/decodificación de URL, hash SHA). Compress PDF es la tercera - reduce un PDF recomprimiendo sus imágenes, también por completo en el dispositivo. El marcador y el texto de su insignia «Se ejecuta en tu dispositivo - nada se sube» cubren ahora todo el conjunto de transformación: Strip Hidden Data, Text Helper, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (destruir regiones de una imagen, SVG o PDF), Prompt to Image y Rebrand a Deck (recambiar el tema de un .pptx in situ) donde el perfil la monte. Es una categoría de utilidades de privacidad que reemplaza el entregar archivos confidenciales a sitios web de un solo propósito.

El cajón de Utilidades, donde cada tarjeta es una herramienta que transforma un archivo que ya tienessigned by Lollyvector SVGCompruébalo tú mismoGet the signed file154 paths~40k nodes234 groups802 KBEl cajón de Utilidades, donde cada tarjeta es una herramienta que transforma un archivo que ya tienessigned by Lollyvector SVGCompruébalo tú mismoGet the signed file154 paths~40k nodes234 groups803 KB

Nota: category y status se desnormalizan en catalog/tools/index.json (el registro que lee la galería) a partir de cada tool.json. El manifiesto es la fuente de verdad - el índice se genera con npm run build:catalog y npm run validate:catalog falla en CI si el índice registrado se desvía de los manifiestos.


Compromisos arquitectónicos

Estas decisiones están cerradas. Cambiar cualquiera de ellas es una empresa mayor - dan forma a cada otra decisión en el código base.

1. Herramientas declarativas, con una vía de escape imperativa

Una herramienta es un manifiesto (tool.json) + una plantilla (template.html) + hooks.js opcional.

El manifiesto declara las entradas. No la plantilla. Las entradas no se infieren de los tokens de Handlebars. El manifiesto es el contrato; la plantilla consume variables con nombre mediante {{id}}.

La pila de controles de Street Map - un desplegable de ciudad, un selector de tema, deslizadores de grosor y disparadores de color, cada uno extraído de una línea del manifiestosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file39 paths~3.4k nodes70 groups2 images50 KBLa pila de controles de Street Map - un desplegable de ciudad, un selector de tema, deslizadores de grosor y disparadores de color, cada uno extraído de una línea del manifiestosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file39 paths~3.4k nodes70 groups2 images50 KB

Los hooks son opcionales. La mayoría de las herramientas son puramente declarativas - manifiesto + plantilla basta. Las herramientas que necesitan valores calculados (codificación QR, formateo de datos de gráficos) proporcionan hooks.js, que expone funciones de ciclo de vida con nombre (onInit, onInput, onFrame - el hook por fotograma de cámara en vivo para herramientas reactivas al movimiento -, onLevel, beforeExport, afterExport, exportFile - la ruta de transformación archivo-a-archivo que usan las utilidades en el dispositivo como Strip Hidden Data - y exportStill, para una herramienta que gestiona su propio ráster en profundidad). El host carga los hooks mediante new Function('host', …) con el puente de capacidades inyectado como ámbito de clausura. Esto es un contrato de portabilidad, no un sandbox de seguridad: los hooks siguen ejecutándose en el ámbito de la página y pueden acceder a window/fetch/document en un shell de navegador - host. es la superficie compatible y portátil, no un límite impuesto. Los resultados de hooks asíncronos tienen un plazo (onInit 5s, onInput 2s, beforeExport/afterExport 5s, exportFile/exportStill 10s) y los resultados tardíos se descartan; un hook síncrono* descontrolado no se puede interrumpir. Por eso, el código de hooks de terceros no confiable no es seguro de ejecutar hasta que llegue el aislamiento en Worker.

Esto importa porque: las herramientas declarativas las pueden crear personas sin perfil de desarrollo. Si cada herramienta fuera una aplicación web, la nota de riesgo «capacidad limitada para crear/mantener plantillas de trabajo» se convierte en un cuello de botella permanente.

2. Las herramientas y los activos son datos, no código empaquetado

Las apps web y Tauri obtienen los catálogos de herramientas y activos desde una URL conocida al arrancar, los guardan en caché local y operan sobre lo que haya ahí. Añadir una nueva tarjeta de evento o un activo de temporada no requiere una nueva versión de la app.

Los bytes de los activos llevan suma de comprobación SHA-256 para evitar el envenenamiento de la CDN. El id + version del activo controla la invalidación de la caché.

3. El puente de capacidades es la única API que ven las herramientas

Las herramientas nunca tocan el DOM fuera del área de su plantilla, nunca llaman a fetch directamente, nunca leen el sistema de archivos. Llaman a métodos versionados host.*. La definición canónica del contrato es packages/core/src/host-v1.ts - el SDK para autores de herramientas @lolly-tools/core, para que un tercero pueda construir contra él sin depender del motor; engine/src/bridge/host-v1.ts es una reexportación de tipos de este, y el código del motor/shell sigue importando desde esa ruta sin cambios:

API del puenteQué hace
host.profileNombre de pila del usuario, correo, foto, ciudad, etc. Prellena entradas mediante bindToProfile.
host.assetsConsultas al catálogo, resolución de activos, interfaz de selector proporcionada por el host.
host.stateGuardar / cargar espacios de entrada. IndexedDB en web, sistema de archivos en Tauri, memoria en CLI.
host.clipboardEscribe texto o imagen en el portapapeles (con alternativas por plataforma).
host.exportRasteriza o serializa el destino de renderizado. Aplica marca de agua para herramientas experimentales.
host.netFetch en lista blanca - solo disponible si la herramienta declaró la capacidad "network". (Ninguna herramienta distribuida la usa actualmente.)

Las superficies opcionales y aditivas aparecen solo cuando un shell las proporciona. Algunas están restringidas por capacidad - expuestas solo cuando la herramienta declara la bandera correspondiente: host.compose (incrustar el renderizado de otra herramienta - compose), host.capture (captura de página para URL Screenshot - capture) y host.recorder (captura de micrófono/cámara/pantalla para las herramientas de grabación - microphone / camera / screen). El resto se detecta por función - presente siempre que el shell pueda proporcionarla, y la herramienta mantiene un respaldo para los shells que no puedan.

Un puñado de superficies destacadas, para mostrar lo que cubre - Host API documenta cada una, y packages/core/src/host-v1.ts es el contrato en sí:

SuperficieDesdeQué añade
host.tokens1.0Tokens de diseño DTCG - las primitivas propias de la marca
host.text1.0Texto a trazado vía HarfBuzz WASM (el indicador de capacidad wasm marca las herramientas que dependen de él)
host.media1.4Fotogramas de cámara en directo que impulsan el hook onFrame. Mejora progresiva, deliberadamente no condicionada por el indicador camera - esa herramienta sigue funcionando como una herramienta de imagen fija normal
host.color1.40Matemáticas de color perceptuales: ΔEOK, contraste WCAG y APCA, degradados OKLab, cortes de clase, paletas categóricas, esquemas de armonía (1.60), mezcla CSS Color 4 y horneado de degradados (1.68). Puro y síncrono - los shells conectan el makeColorApi() del motor en lugar de implementar nada, así que no puede desviarse
host.images1.60Decodificar / redimensionar / recodificar bytes en el dispositivo - la ruta de conversión (HEIC → JPEG, comprimir a WebP, reducir escala). Distribuido en el shell web como una fachada perezosa, así que el decodificador HEIC nunca entra en el fragmento de arranque
host.geom1.64Geometría vectorial exacta: booleanos de trazados, desplazamiento, contorno a relleno, reducción de splines, simplificación, detección de colisiones. También puro, síncrono y conectado desde el motor (makeGeomApi()); los fallos se devuelven, nunca se lanzan

El resto sigue las mismas reglas y está documentado junto a ellas: pdf (1.8) y pptx (1.58) para cirugía de documentos en el dispositivo, audio (1.71) y speech (1.96) para análisis de clips y TTS/transcripción en el dispositivo, viz (1.72) para el contrato de sustituto de MilkDrop, codec (1.100) y layers (1.102) para salida en profundidad de bits y de mapa de bits por capas, upscale (1.101) y matte (1.103) para los modelos en el dispositivo, raster (1.105) para hooks que hacen su propio trabajo de píxeles, connectors (1.106) para flechas seguras para exportación y c2pa (1.85) para firmar bytes finalizados. La lista crece; las reglas no.

Las capacidades declarables son: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, añadida en 1.54, es captura de pantalla vía host.recorder - el usuario elige una pantalla/ventana/pestaña en la interfaz nativa del navegador; distinta de capture, que rasteriza una URL que la propia herramienta indica.)

La misma herramienta se ejecuta en navegador, Tauri y CLI sin interfaz porque cada shell implementa esta interfaz - la herramienta nunca sabe en cuál está.

El puente está versionado. Añadir métodos es una versión menor. Eliminar o cambiar firmas es un salto de versión mayor. Cuando salga v2, v1 debe seguir funcionando.

4. Los ID de activo son para siempre

suse/logo/primary es un contrato. Una vez publicado:

Esto hace que los estados de herramienta guardados y los enlaces compartidos por URL sean duraderos a través de los años.

5. El modo URL es de primera clase

Cada entrada debe poder expresarse como un parámetro de URL:

lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H

Ese enlace por sí solo, sin nada más en él, es el activo terminadosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file17 paths~2.0k nodes39 groups24 KBEse enlace por sí solo, sin nada más en él, es el activo terminadosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file17 paths~2.0k nodes39 groups24 KB

El modo CLI es el modo URL bajo un transporte distinto - el shell de CLI construye un objeto de estado de URL a partir de argv y ejecuta la misma cadena del motor. Hay una sola ruta de renderizado. La CLI no puede desviarse de la GUI porque no es una implementación aparte.

url-mode.ts gestiona el ciclo completo (parsear y serializar). Un conjunto de parámetros reservados nunca se reenvía a la herramienta como entradas: los controles de salida (format, export, copy, filename, width/w, height/h, unit, dpi), los mandos de impresión y procedencia (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) y los portadores de estado (template, z - el token empaquetado de «Enlace más corto» - y zx, el mismo cifrado con contraseña). El conjunto RESERVED en engine/src/url-mode.ts es la autoridad y está fijado por una prueba; URL Mode documenta cada uno de ellos, incluidos los pocos que no se listan aquí. Las entradas de activo en modo URL se serializan por su id; el runtime las resuelve mediante host.assets.get() antes de la hidratación. width/height son valores en unit (por defecto px, también mm/cm/in/pt/pc); con una unidad física, dpi fija la resolución de ráster. Establecen el tamaño del documento del lienzo y prellenan el panel de dimensiones de exportación.

Porque cada entrada viaja en el enlace, un cambio de parámetro es un activo terminado distinto. Toda esta paleta es un color semilla, una armonía y un número de pasos:

Nueve pasos en cuatro matices, todos generados a partir del único color semilla que lleva el enlacesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file10 groups24 KBNueve pasos en cuatro matices, todos generados a partir del único color semilla que lleva el enlacesigned by Lollyvector SVGCompruébalo tú mismoGet the signed file10 groups24 KB

6. El almacenamiento pasa por el bridge, no directamente

Web shell: IndexedDB. Tauri: sistema de archivos. CLI: en memoria. Las herramientas solo ven host.state.save(slot, data) y host.state.load(slot). localStorage no se usa: es demasiado pequeño y no puede contener blobs.

Los usuarios pueden guardar varias ranuras de edición con nombre por herramienta y retomar cada sesión más tarde. No hace falta crear una cuenta; el estado es por dispositivo. Como el bridge es el único punto de paso, ese estado por dispositivo también es portable: shells/web/src/data-transfer.ts lee todo de vuelta a través de host.profile/host.state/host.assets en un único zip lolly-backup que se importa en cualquier otra instalación - la respuesta sin conexión a "pasar a un dispositivo nuevo" que no necesita servidor (especificación completa: docs/data-transfer.md). La integración con SUSE ID (sincronización entre varios dispositivos) es un hito futuro sobre esta base.

7. Las etiquetas de madurez responden por diseño al riesgo de "aprobado por la marca"

Cada herramienta declara status: official | community | experimental en su manifiesto. La galería ordena por estado. Las herramientas experimentales marcan sus exportaciones con marca de agua automáticamente - la marca de agua la aplica host.export.render, no la herramienta, así que un autor de herramientas no oficial no puede desactivarla.

Esta es una respuesta estructural al riesgo de percepción de que usar cualquier herramienta implica aprobación de la marca. Las respuestas de proceso (una cola de revisión, control de acceso por SUSE ID) se suman encima.

8. Las entradas de las herramientas están tipadas mediante el manifiesto, incluidos los assets

Las entradas declaran un type: text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table y file. El host renderiza un control genérico por tipo a partir del manifiesto - las herramientas no escriben código de control. (El prellenado desde el perfil del usuario no es un tipo; cualquier entrada puede llevar bindToProfile.) Tres pesan más que el resto:

9. Las plantillas no tienen lógica (Handlebars, no EJS)

Handlebars se eligió sobre EJS deliberadamente:

La lógica vive en hooks.js, donde es explícita y revisable. Helpers de Handlebars disponibles: {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (además de los helpers de formato de datos icsStamp/rfcText/csvCell usados por las plantillas hermanas .ics/.vcf/.csv).

10. Las herramientas componen herramientas

Una herramienta puede incrustar el render de otra herramienta sin importaciones entre herramientas - la composición la resuelve el motor, nunca el código de la herramienta. Hay dos superficies:

Compón el render de cualquier herramienta: una hija SVG sigue siendo un vector real cuando el padre exporta a SVG o PDF y se rasteriza con nitidez para PNG; las hijas PNG/JPG/WEBP se incrustan como imágenes. Requiere la capacidad compose. Las hijas compuestas son intermedias - nunca llevan marca de agua ni sello de procedencia - y la composición se degrada con elegancia: un shell que no puede renderizar una hija simplemente omite ese hueco y el padre igualmente se renderiza.


Lo que decidimos explícitamente no hacer


Ciclo de vida, de principio a fin

Un usuario abre lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H:

  1. Arranque. El web shell abre IndexedDB, construye el bridge de capacidades, sincroniza los catálogos de herramientas y assets (o carga desde la caché sin conexión).
  2. Ruta. El hash de la URL → la vista tool, con qr-code y los parámetros de URL extraídos.
  3. Carga. loadTool('qr-code', fetchFile) obtiene tool.json, lo valida contra el JSON Schema, y obtiene el origen de template.html, styles.css y hooks.js.
  4. Análisis del estado de la URL. parseUrlState traduce los parámetros de URL a valores de entrada iniciales. Las referencias a assets (?logo=suse/logo/primary) se analizan como objetos ligeros { id, _unresolved: true }.
  5. Runtime. createRuntime(tool, host, initialValues) construye el modelo de entrada (combinando datos del perfil, valores por defecto y valores iniciales), resuelve las referencias a assets mediante host.assets.get(), carga los hooks (host con ámbito de clausura, no aislado) y llama a hooks.onInit.
  6. Renderizado. El shell se suscribe al runtime; en cada cambio de estado recibe { model, hydrated }. Renderiza los controles de entrada a partir del modelo y escribe el HTML de la plantilla hidratada en #tool-canvas.
  7. Interacción. El usuario escribe en una entrada → runtime.setInput(id, value) → se aplican las restricciones → se llama a hooks.onInput → se rehidrata → se vuelve a renderizar. El lienzo se actualiza en vivo.
  8. Exportación. El usuario hace clic en Descargar (PNG) → runtime.export(canvasNode, 'png')host.export.render (rasteriza mediante dom-to-image-more; SVG/PDF pasan por vectorizadores dedicados que recorren el DOM) → blob → host.export.download. El abanico de formatos al que puede optar una herramienta es amplio, y el enum render.formats en schemas/tool.schema.json es la autoridad al respecto - rasters y rasters de coma flotante, vectores y archivos de corte, impresión/CMYK, movimiento, documentos editables (pptx, docx, odt), salidas de paleta y de datos/texto, archivos de audio y de fuentes. URL Mode nombra cada id y lo que produce. El audio está en ese enum como cualquier otra cosa (wav, mp3, m4a, opus, declarados por el audiograma y las herramientas de grabación); por separado, el modo render.capture de una herramienta de grabación activa host.recorder, cuya toma llega como un Blob terminado en el contenedor que el navegador haya grabado. (Las herramientas que fijan render.export: false - p. ej. Color Palette, Countdown Timer, Strip Hidden Data, Text Helper, Compress PDF - ocultan los controles de descarga/formato/dimensiones.) Las unidades físicas se convierten por formato aquí (PDF → puntos de página reales, raster → píxeles a la DPI con un chunk pHYs). Los metadatos de autoría/procedencia (autor, herramienta, fuente - construidos por engine/src/metadata.ts) se incrustan por formato: PNG iTXt, JPEG EXIF, diccionario de información de PDF, <metadata> de SVG, comentario de GIF. Las herramientas experimentales reciben una marca de agua insertada por el host, no por la herramienta.

El panel de exportación que abre ?options: el par nombre de archivo y formato, el tamaño de salida y los controles que escriben el archivosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file49 paths~3.3k nodes61 groups3 images74 KBEl panel de exportación que abre ?options: el par nombre de archivo y formato, el tamaño de salida y los controles que escriben el archivosigned by Lollyvector SVGCompruébalo tú mismoGet the signed file49 paths~3.3k nodes61 groups3 images74 KB

Mismo ciclo de vida en Tauri. Mismo ciclo de vida en CLI - jsdom proporciona el DOM sin interfaz gráfica; la salida va a un archivo o a stdout.


Estado de código abierto

El código es MPL-2.0. engine/, shells/, services/, schemas/ y docs/ son de código abierto bajo MPL-2.0 - una plataforma de scaffolding neutral respecto al proveedor para herramientas de marca, con cada unidad distribuible en su propio repositorio bajo github.com/lolly-tools.

El contenido de las herramientas se distribuye como brand packs, cada uno con sus propios términos (consulta el NOTICE.md del pack). community/ es el repositorio público lolly-tools y sus herramientas independientes de marca también son MPL-2.0. brands/suse/ es el pack privado suse-lolly: las herramientas de SUSE y el catálogo de SUSE, propiedad exclusiva de SUSE, incluida su música con licencia de PremiumBeat. brands/lolly-start/ es la marca inicial en blanco que posee este repositorio. Las fuentes se distribuyen dentro de un pack bajo la SIL Open Font License 1.1 - el pack de SUSE lleva las tipografías SUSE y SUSE Mono.

Los directorios tools/ y catalog/ en la raíz del repo son vistas ignoradas por git: un perfil los ensambla a partir de community/ más el brand pack activo, por lo que cada script y shell lee esas dos rutas y nunca un pack directamente.

La separación se hace cumplir - no hay importaciones cruzadas de engine/ hacia el contenido de las herramientas - así que el límite entre plataforma y contenido se mantiene limpio.


Dónde termina el motor y dónde empieza el host

Si puedes describirlo en datos puros + Handlebars → motor. Si toca el DOM, el sistema de archivos, la red o cualquier API del navegador/SO → host.

La línea es nítida a propósito. El motor es la parte de código abierto. Todo lo que sabe sobre SUSE, plataformas concretas o entornos de ejecución queda fuera de él.

Para el siguiente nivel de detalle, engine/README.md enumera cada módulo del motor y de qué se encarga, y Threat Model & Trust Boundaries recoge dónde esa misma línea funciona también como límite de confianza.