Lolly
Ouvrir l'app

Aperçu

signed by Lollyoverview.htmlHTMLpixels, not shapes12 KBAI generatedgenerated by ClaudeVérifie par toi-mêmeRécupérer le fichier signé

Icône Lolly - Grande sucette verte et blanche

Ce document décrit l'objectif, la structure et les décisions architecturales de la plateforme Lolly. Il reflète à la fois la vision produit et l'état actuel du code.

Statut : Lolly est publié. La version 1.0 est sortie en open source sous MPL-2.0 le 30 août 2026, et les fonctionnalités, les réglages par défaut et le catalogue d'outils continuent d'évoluer d'une version à l'autre. Le moteur est déterministe, avec un seul chemin de rendu derrière chaque shell. Sa sécurité n'a pas encore fait l'objet d'un audit indépendant, et les preuves d'adoption datent de quelques mois. Voir Adoption et gouvernance pour l'état actuel et la façon dont l'adoption est mesurée.

Comment lire cette page. Elle contient deux types de contenu, dans l'ordre. La première moitié explique pourquoi cela existe : le problème, le positionnement et le cycle de vie qu'un seul asset parcourt. À partir de La vue d'ensemble, il s'agit de comment les couches s'articulent : le document d'architecture pour les contributeurs, couvrant la séparation moteur/coquille/pack, la disposition du dépôt, les cibles de livraison et les engagements qui contraignent chaque changement de la plateforme. Si tu es ici pour modifier le code plutôt que pour comprendre le produit, commence par la vue d'ensemble.

Deux documents compagnons vont plus loin que cette page. engine/README.md dans le dépôt est la carte module par module du moteur, avec un tableau généré de chaque module et de ce qu'il analyse ou écrit. Modèle de menace et limites de confiance reprend la même architecture lue sous l'angle des limites de confiance, et c'est la bonne page pour toute question sur ce que le moteur traite comme non fiable.


Pourquoi cela existe

Le travail créatif répétitif est trop prévisible pour justifier des mains expertes à chaque fois, et trop sensible à la qualité pour être délégué sans garde-fous. Livré à lui-même, il prend l'une de ces trois voies : lent, incohérent ou enfermé dans les modèles d'un fournisseur.

Cette plateforme est la réponse directe :

Du créatif et du contenu programmatiques à grande échelle - des ressources générées à partir d'entrées, avec les règles fixées une fois, pour qui en a besoin.

Lolly n'est pas l'endroit où un système de marque s'invente - c'est l'endroit où il se produit. Pense à un distributeur automatique pour le design : tu fais un choix, tu obtiens un résultat. À chaque fois. Le moteur vise la plus haute qualité que chaque format puisse produire sur le matériel que tu as sous la main, et le même moteur produit le même fichier sur chaque surface où il est livré.

Le résultat est l'abondance : chaque événement a une signalétique correcte, chaque alerte CVE respecte la charte, chaque étiquette s'imprime proprement, chaque signature e-mail est à jour - tout cela à partir d'outils qui portent déjà les règles. La plateforme gère le créatif opérationnalisé récurrent. Ce n'est délibérément pas un outil créatif sur mesure - les designers continuent de posséder le travail phare.

Innover de façon probabiliste, passer à l'échelle de façon déterministe

Tout débat sur l'IA dans un pipeline créatif bute sur la même question : quelle part revient à la machine ? C'est une vieille question dont la réponse est établie. Les scribes et les enlumineurs travaillaient déjà entre deux instruments - l'esquisse libre, où rien n'était fixé et tout pouvait être tenté, et la presse à imprimer, intimidante justement parce qu'elle engageait. Les esquisses étaient là où l'art se produisait. La presse était le moyen de l'atteindre. Personne ne confondait les deux, et les deux ont continué à progresser - nouvelles encres, nouveaux caractères, nouvelles presses - chacune s'améliorant en harmonie avec l'artisanat et l'intention qu'elle servait.

Lolly trace la même ligne. Explore de façon probabiliste : un modèle, un designer, une idée brute, une invite qui mène quelque part que personne n'avait prévu. Puis passe à l'échelle de façon déterministe - ce qui devient de nombreuses sorties est un outil, et un outil se restitue de la même manière à chaque fois à partir d'entrées que tu peux lire. L'exploration reste libre parce que rien en aval ne dépend qu'elle aboutisse de la même façon deux fois. Le résultat gagne la confiance parce que ce n'est pas une supposition. Faire passer l'expérimentation par IA à des résultats prévisibles et reproductibles n'est pas une discipline nouvelle ; c'est la même division du travail qui a rendu l'imprimé digne de confiance à l'origine.

Fais confiance au processus créatif, passe à l'échelle avec rigueur.

Face aux alternatives

Lolly includes lolly.work, the same project's separately deployed organisation service. Local creation needs no account; shared work and server rendering use the configured instance. Competitor scores: August 2026. Lolly coverage: 28 September 2026.

Capability Lolly+ lolly.work 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: version 1.0 public since 30 August 2026 under MPL-2.0, and SUSE runs it as an internal deployment; no usage data is shared yet and there are no public case studies yet. 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 and CLI, plus lolly.work's recoverable server jobs and batches with retries, cancellation and retained outputs. 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: standalone creation works offline once its assets are available; lolly.work's organisation services need a reachable instance, which can run on an internal network. 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: local rendering and conversion in-browser or CLI need no upload. Choosing lolly.work's shared storage, work collabs or server rendering sends the relevant data to the configured instance. 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: templates fix layout rules and expose permitted inputs. lolly.work adds group access, input policies, shared catalogues, approvals and audit records. Copy and usage rights can still need review. 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: optional on-device signing without an account, plus lolly.work server signing with a configured organisation identity. A verifier must trust the signer's root to show a trusted identity. Version 1.0 is public and SUSE runs it internally, but no usage data is shared yet, so 75. Penpot: 50 via the official Lolly Export plugin - the same on-device engine signing Lolly uses, opt-in, as in Lolly (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 and URL mode, plus lolly.work's authenticated render API, recoverable batches and governed delivery. One engine across the local and server paths. 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)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: direct two-device private collabs without an account, plus authenticated work collabs through lolly.work with shared edits, cursors and saved team sessions. Partial reflects the current single-node work deployment and limited operating history. Private collabs work without internet on a shared network; work collabs need the organisation's instance. 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 using an existing tool, or publish a tool from Design through Share with rules. lolly.work manages access and input policy for the team. 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 and lolly.work: MPL-2.0 open source in separate repositories, both self-hostable. lolly.work provides the organisation services as part of the project. The current 75 reflects the young project and limited deployment history. Everything else is proprietary SaaS or proprietary desktop.
75 100 0 0 0 0 0 0
Cost at production scaleLolly + lolly.work and Penpot: no per-seat software licence charge for the open-source self-hosted path; hardware, storage and operations remain costs. 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 + lolly.work: US$0 in software licence charges for self-hosting. The figure excludes devices, organisation hosting, storage, support and administration; these need a separate budget. Standalone Lolly does not need the organisation service. Cloudinary: US$30k-150k, credit-based; enterprise contracts commonly sit near US$82k.
$0 $0 $400k $500k $250k+ $150k $250k $60k

Exhaustivité des fonctionnalités des outils créatifs actuels, étudiée en août 2026. Notation : 0 absent, 25 solution de contournement, 50 réel mais restreint ou partiel, 75 solide avec réserves, 100 compétence de base.

signed by Lollypositioning-comparison.htmlHTMLpixels, not shapes40 KBAI generatedgenerated by GPT-6Vérifie par toi-mêmeRécupérer le fichier signé

L'écart est évident : rien de ce qui est actuellement disponible n'offre une sortie axée sur les contraintes, capable de fonctionner hors ligne, accessible sans compétence pointue et en interne. Lolly comprend même un canevas ouvert - Design - où les couleurs, la typographie et les ressources se conforment aux globaux de marque, si bien que la disposition libre reste axée sur les contraintes. Ce que ce n'est pas, c'est une suite de design sans contraintes : les designers continuent d'utiliser Illustrator et Figma pour le travail phare sur mesure. Des permutations peuvent être assemblées avec cet outil.

Chaque outil de la bibliothèque sous forme de carte, groupé par catégorie, pour qu'un producteur en choisisse un et commence signed by Lollyvector SVG367 paths~62k nodes773 groups3 images1 453 KBVérifie par toi-mêmeRécupérer le fichier signéChaque outil de la bibliothèque sous forme de carte, groupé par catégorie, pour qu'un producteur en choisisse un et commence signed by Lollyvector SVG367 paths~62k nodes776 groups3 images1 454 KBVérifie par toi-mêmeRécupérer le fichier signé

À utiliser pour : la génération rapide de ressources créatives opérationnalisées - tuiles d'événement, badges nominatifs, signatures, alertes CVE, codes QR, cartes sociales, étiquettes de consignation, rapports structurés.

À ne pas utiliser pour : le contenu phare sur mesure.


Le cycle de vie d'une campagne

La façon la plus claire de voir ce qu'est Lolly n'est pas une liste de fonctionnalités - c'est de suivre une seule ressource au fil de son passage de main en main. Observe une carte de campagne localisée circuler dans l'organisation :

  1. Le créatif fixe les règles. Un designer crée le modèle de base dans l'outil Design, en codant en dur les variables de typographie et de couleur de la marque. Il ne fait pas une seule carte - il fait le travail fondamental une fois pour ne plus jamais avoir à la localiser à la main.
  2. Le développeur le déploie à grande échelle. Ce même modèle est intégré dans un pipeline nocturne via la CLI, si bien qu'un nouveau graphique ou une nouvelle variante linguistique est généré automatiquement - personne ne rouvre le fichier.
  3. Le producteur l'utilise simplement. Un commercial, hors ligne dans un avion, ouvre le même outil et génère une présentation parfaitement conforme à la marque pour un rendez-vous client. Aucune compétence en design, aucun réseau, aucune attente.

Le « nouveau graphique » de l'étape deux est une restitution comme celle-ci, produite à partir d'une chaîne de données et d'une poignée de paramètres, sans que personne n'ouvre un fichier de design :

Un graphique en aires empilées avec titre, ses trois séries en bandes dans une palette froide, avec axes, légende et titre tous placés par le modèle plutôt qu'à la main signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBVérifie par toi-mêmeRécupérer le fichier signéUn graphique en aires empilées avec titre, ses trois séries en bandes dans une palette froide, avec axes, légende et titre tous placés par le modèle plutôt qu'à la main signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBVérifie par toi-mêmeRécupérer le fichier signé

Le point n'est pas que Lolly soit bon pour les designers et bon pour les développeurs et bon pour les commerciaux, chacun dans son coin. C'est une course de relais : le travail initial du créatif est déployé à l'échelle par le développeur, qui à son tour donne du pouvoir au producteur. L'expérience sans effort pour le commercial non technique dans l'avion n'est possible que grâce à la rigueur fixée par le designer et déployée par le développeur.

C'est le multiplicateur de force. Lolly n'est pas un tiroir d'outils séparés pour des rôles séparés - c'est un seul cycle de vie déterministe des ressources auquel chaque rôle contribue, et chaque main par laquelle il passe multiplie la valeur de la précédente.


Un outil, de nombreuses sorties

Les règles de marque vivent dans l'outil, pas dans chaque fichier qu'il produit (voir Comment Lolly se compare). Mets l'outil au point une fois, et chaque sortie hérite de la même typo, de la même couleur et du même espacement, qu'il s'agisse d'une carte ou d'un tableur de lignes en une douzaine de langues. Comment tu vérifies ton travail, et qui le fait, ça reste à toi ; Lolly rend la chose à vérifier plus petite et la sortie plus rapide à produire.

Le même outil déterministe atteint cette échelle de trois façons, toutes produisant une sortie identique :

Le mode Batch sur une installation fraîche : une ligne vide attend un outil, avec toute la surface façon tableur et son bouton Rendre déjà en place avant l'arrivée de données signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBVérifie par toi-mêmeRécupérer le fichier signéLe mode Batch sur une installation fraîche : une ligne vide attend un outil, avec toute la surface façon tableur et son bouton Rendre déjà en place avant l'arrivée de données signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBVérifie par toi-mêmeRécupérer le fichier signé

Un seul jeu de contraintes de marque, fixé une fois par un designer ; trois voies vers la sortie identique.


La vue d'ensemble : comment les couches s'articulent

Tout ce qui suit relève de l'architecture. Le diagramme est le système entier en une seule vue : les outils sont des données en haut, le moteur au milieu ne connaît aucune plateforme, les coquilles en dessous mettent en œuvre un seul contrat, et les catalogues fournissent le contenu.

                ┌─────────────────────────────────────────────┐
                │              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   │
                └─────────────────────────────────────────────┘

Disposition du dépôt

Lolly est un seul dépôt. engine/, schemas/, scripts/, tests/, api/, docs/, community/, brands/lolly-start/, chaque shells/ et les deux services/ sont de simples répertoires qu'il contient. La seule exception est brands/suse, un sous-module git privé contenant le pack d'outils et le catalogue SUSE, optionnel et absent d'un clone public. Les packs que lit une build donnée dépendent d'un profil de contenu (profiles.json), résolu par processus plutôt que changé globalement. Voir Guide de build » Récupérer les sources pour la commande de clonage et la façon de committer un changement dans le pack privé.

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
│
├── community/        # the brand-agnostic tool pack - data, not code. Public (MPL-2.0).
│                     #   A SELECTION follows; a profile mounts these plus whatever
│                     #   tools the active brand pack carries of its own.
│   ├── qr-code/
│   ├── snippet/
│   ├── countdown-timer/
│   ├── color-palette/
│   ├── 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)
│   ├── chart/             # 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
│   ├── 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
│   ├── icon/              # favicon .ico / png / svg from text + colours
│   └── lottie-digi-ad/    # animated Lottie ad banners
│
├── brands/            # brand packs - a catalog each, and optionally tools of their own
│   ├── lolly-start/   # the blank starter brand, owned here
│   │   └── catalog/
│   │       ├── tools/index.json    # tool registry, generated per brand
│   │       └── assets/
│   │           ├── index.json      # asset registry
│   │           └── lolly/...       # logo, palette, tokens
│   └── suse/          # PRIVATE submodule - the SUSE tools and the SUSE catalog
│
├── 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

Modèle de livraison de la plateforme

La plateforme fonctionne sur plusieurs surfaces - PWA web, Tauri desktop/mobile, la CLI scriptable et le TUI interactif. Toutes utilisent le même moteur et les mêmes fichiers d'outils.

Web (PWA) - distribution principale

Hébergée sur une URL contrôlée par SUSE. Fonctionne hors ligne une fois que le service worker a mis en cache les outils et les ressources. C'est ici que la plupart des employés, fournisseurs et partenaires utiliseront la plateforme. Aucun compte requis - l'état est stocké dans IndexedDB par appareil.

La coquille web est responsive depuis une seule mise en page. Sur ordinateur, un outil se présente comme une barre latérale de contrôles redimensionnable à côté d'une scène d'aperçu avec une navigation du canevas native au trackpad (Cmd/Ctrl-molette ou pincement pour zoomer autour du curseur, glissement avec Espace ou clic central pour se déplacer, les touches 0/1/+/− et un HUD Fit/%). Sur mobile (≤640px), les contrôles deviennent une feuille ancrée en haut avec une poignée de glissement qui s'aligne sur peek/moitié/plein (un tap bascule) au-dessus d'un aperçu plein écran statique, et un bouton flottant Render ouvre les contrôles Export dans une fenêtre contextuelle en feuille du bas. Le tactile obtient le pincement pour zoomer et le glissement pour se déplacer sur l'aperçu. Le chemin de restitution et les contrôles d'export sont identiques dans les deux cas - seule l'interface se réorganise.

La vue partagée du bureau - les contrôles générés depuis le manifeste à gauche, le canvas en direct à droite signed by Lollyvector SVG131 paths~6.1k nodes158 groups1 image142 KBVérifie par toi-mêmeRécupérer le fichier signé

Le même outil en largeur téléphone, sans second layout à maintenir : les contrôles deviennent une feuille en haut, l'aperçu occupe tout l'écran et la pastille de rendu flotte par-dessus.

Un audiogramme sur un écran de 430px de large - la feuille de contrôles en haut, l'illustration carrée finie en bas et la pastille de rendu flottante signed by Lollyvector SVG97 paths~3.3k nodes113 groups99 KBVérifie par toi-mêmeRécupérer le fichier signéUn audiogramme sur un écran de 430px de large - la feuille de contrôles en haut, l'illustration carrée finie en bas et la pastille de rendu flottante signed by Lollyvector SVG97 paths~3.3k nodes113 groups100 KBVérifie par toi-mêmeRécupérer le fichier signé

Mode batch (/pro). Le shell web embarque aussi une grille batch façon tableur (shells/web/src/pro/) qui rend de nombreuses lignes à la fois sur un ou plusieurs outils. Il gère l'aller-retour CSV/TSV plus le collage tableur, le template/format/taille/unité/dpi par ligne, un panneau latéral éditeur de blocs avec aperçu en direct, des colonnes d'export repliables, une barre de tags de « pertinence » par ligne, la réorganisation des lignes par poignée de glisser à gauche, une confirmation de suppression en deux temps, des sessions batch sauvegardées et un téléchargement .zip. C'est la surface un-vers-plusieurs derrière le positionnement « génération de contenu en masse ».

Bureau / mobile Tauri

Application native packagée (petite empreinte via Tauri). Fournit une disponibilité hors ligne complète, un accès au système de fichiers pour les outils dépendant de la CLI (PDF Smasher, Font Outliner) et l'accès caméra. Amélioration de l'outillage prévue mi-2026.

CLI

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

Les utilisateurs de bureau peuvent invoquer de nombreux outils depuis le terminal. Le shell CLI charge le même moteur, crée un DOM jsdom, exécute le même chemin de rendu et écrit le fichier. Le mode URL est le transport - la CLI n'est pas une implémentation séparée. Cela garantit que les sorties CLI et GUI sont identiques.

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

pnpm run tui

L'équivalent interactif de la CLI : une application terminal plein écran, pilotée au clavier (construite sur Ink) pour parcourir les outils, remplir les entrées, sauvegarder des projets et exporter - tout cela sans GUI. Son pont hôte réutilise l'implémentation de la CLI pour les formats sans DOM (SVG/EMF/EPS/HTML + texte/données), et ajoute un état sur disque sous ~/.lolly plus un aperçu en ligne optionnel. Au-delà, elle dispose d'un palier de rendu navigateur : un Chromium headless dédié (le même que celui installé par le serveur MCP) qui produit du raster/PDF/vidéo et de la capture d'URL en direct à la demande - en pilotant une copie compilée du shell web pour que la sortie soit identique, et en ne se lançant qu'au premier export d'un tel format. Ainsi url-shot (avec recadrage + recoloration + PDF/SVG vectoriel) et tous les outils raster/pdf tournent aussi dans le terminal. Voir le guide TUI.

Quelle que soit la surface sur laquelle tu es, l'onglet Capabilities du tableau de bord est la carte complète de ce que la plateforme déclare pouvoir faire, groupée et lisible sans ouvrir un seul outil.


Catégories d'outils

Les outils sont étiquetés avec une category dans leur manifeste pour le regroupement dans la galerie.

Les lignes sont listées dans l'ordre des sections de la galerie. La section utility s'affiche toujours en dernier dans la galerie (après toute autre catégorie, y compris les futures) - c'est le tiroir « Outils hors ligne » sur l'appareil.

CatégorieExemplesPrévu
everyoneQR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence, RecordEmployee Image Stationery
designerBrand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, BookletFont 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, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL ScreenshotConvertisseurs d'unités/formats, autres utilitaires de confidentialité sur l'appareil

Ces cellules sont des exemples, pas des inventaires. Les outils existants dépendent du profil que tu as monté, pas de cette page : un pack de marque ajoute les siens, et peut exclure un outil communautaire qu'il préfère ne pas livrer. catalog/tools/index.json - généré depuis les manifestes, et le registre que la galerie lit réellement - est la liste faisant autorité ; pour compter ce qu'un profil monte, compte les manifestes (ls community//tool.json brands//tools/*/tool.json) plutôt que de te fier à un nombre écrit ici. (Un id d'outil présent dans deux packs se monte une seule fois, depuis le pack gagnant.)

Les outils sont aussi classés par statut : official (approuvé par la marque, pas de filigrane), community (contribution externe), experimental (exports filigranés). L'essentiel de la bibliothèque est official ; les studios les plus récents et les outils de capture ont tendance à rester en community ou experimental le temps de se stabiliser. Chaque surface affiche le badge, pour que le lecteur sache ce qu'il récupère avant d'ouvrir l'outil - et, comme les cellules de catégorie ci-dessus, l'appartenance par statut bouge trop vite pour être énumérée ici. Lis-la depuis la galerie ou l'index généré.

Design est le premier outil construit sur le mode canvas libre render.layout: "editor" - une surface sans chrome, à manipulation directe, où tu déplaces, redimensionnes, fais pivoter et aimantes des boîtes de texte, de formes et d'images, puis exportes via le même chemin de rendu que tout autre outil.

Strip Hidden Data est le premier utilitaire sur l'appareil (privacy: "on-device") : un outil de transformation de contenu qui prend un fichier fourni par toi, le traite entièrement dans le navigateur et te rend une copie propre - jamais envoyée, jamais filigranée, sans tampon de provenance. Text est le deuxième - un atelier sur l'appareil pour les tâches courantes de copier-coller web (formatage JSON, décodage JWT, Base64, encodage/décodage URL, hachage SHA). Compress PDF est le troisième - il réduit un PDF en recompressant ses images, là encore entièrement sur l'appareil. Le marqueur et le texte de son badge « Fonctionne sur ton appareil - rien n'est envoyé » couvrent désormais tout l'ensemble de transformation : Strip Hidden Data, Text, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (effacer des zones d'une image, d'un SVG ou d'un PDF), Prompt Card et Rebrand (rethémer un .pptx sur place) là où le profil le monte. C'est une catégorie d'utilitaires de confidentialité qui remplace le fait de confier des fichiers confidentiels à des sites web à usage unique.

Le tiroir Utilities, où chaque carte est un outil qui transforme un fichier que tu possèdes déjà signed by Lollyvector SVG124 paths~29k nodes324 groups395 KBVérifie par toi-mêmeRécupérer le fichier signéLe tiroir Utilities, où chaque carte est un outil qui transforme un fichier que tu possèdes déjà signed by Lollyvector SVG124 paths~29k nodes324 groups396 KBVérifie par toi-mêmeRécupérer le fichier signé

Remarque : category et status sont dénormalisés dans catalog/tools/index.json (le registre que lit la galerie) à partir de chaque tool.json. Le manifeste fait foi - l'index est généré par pnpm run build:catalog, et pnpm run validate:catalog fait échouer la CI si l'index committé diverge des manifestes.


Engagements architecturaux

Ces décisions sont arrêtées. En changer une est une entreprise majeure - elles façonnent chaque autre décision de la base de code.

1. Outils déclaratifs, avec une échappatoire impérative

Un outil, c'est un manifeste (tool.json) + un template (template.html) + optionnellement hooks.js.

Le manifeste déclare les entrées. Pas le template. Les entrées ne sont pas déduites des tokens Handlebars. Le manifeste est le contrat ; le template consomme des variables nommées via {{id}}.

La pile de contrôles de Street Map - un menu déroulant de ville, une sélection de thème, des curseurs d'épaisseur et des déclencheurs de couleur, chacun tiré d'une ligne du manifeste signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBVérifie par toi-mêmeRécupérer le fichier signéLa pile de contrôles de Street Map - un menu déroulant de ville, une sélection de thème, des curseurs d'épaisseur et des déclencheurs de couleur, chacun tiré d'une ligne du manifeste signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBVérifie par toi-mêmeRécupérer le fichier signé

Les hooks sont optionnels. La plupart des outils sont purement déclaratifs - manifeste + template suffisent. Les outils nécessitant des valeurs calculées (encodage QR, mise en forme de données de chart) fournissent un hooks.js exposant des fonctions de cycle de vie nommées (onInit, onInput, onFrame - le hook caméra en direct par image pour les outils réactifs au mouvement - onLevel, beforeExport, afterExport, exportFile - le chemin de transformation fichier-entrée/fichier-sortie utilisé par les utilitaires sur l'appareil comme Strip Hidden Data - et exportStill, pour un outil qui gère son propre raster en profondeur). L'hôte charge les hooks via new Function('host', …) avec le pont de capacités injecté comme portée de fermeture. C'est un contrat de portabilité, pas un bac à sable de sécurité : les hooks s'exécutent toujours dans le contexte de la page et peuvent accéder à window/fetch/document dans un shell navigateur - host. est la surface prise en charge et portable, pas une frontière imposée. Les résultats asynchrones des hooks sont chronométrés (onInit 5 s, onInput 2 s, beforeExport/afterExport 5 s, exportFile/exportStill 10 s) et les résultats tardifs sont écartés ; un hook synchrone* incontrôlé ne peut pas être préempté. Le code de hook tiers non fiable n'est donc pas sûr à exécuter avant l'arrivée de l'isolation Worker.

Cela compte parce que : les outils déclaratifs peuvent être créés par des non-développeurs. Si chaque outil était une application web, la note de risque « compétences limitées pour créer/maintenir des templates de production » devient un goulot d'étranglement permanent.

2. Les outils et les assets sont des données, pas du code embarqué

Les applications web et Tauri récupèrent les catalogues d'outils et d'assets depuis une URL connue au démarrage, les mettent en cache localement et fonctionnent avec ce qui s'y trouve. Ajouter une nouvelle tuile d'événement ou un asset saisonnier ne nécessite pas de publication d'application.

Les octets d'assets sont vérifiés par somme de contrôle SHA-256 pour empêcher l'empoisonnement de CDN. L'id + la version de l'asset pilotent l'invalidation du cache.

3. Le Capability Bridge est la seule API que les outils voient

Les outils ne touchent jamais au DOM en dehors de leur zone de template, n'appellent jamais fetch directement, ne lisent jamais le système de fichiers. Ils appellent des méthodes host.* versionnées. La définition canonique du contrat est packages/core/src/host-v1.ts - le SDK auteur-d'outils @lolly-tools/core, pour qu'un tiers puisse construire dessus sans dépendre du moteur ; engine/src/bridge/host-v1.ts en est une réexportation de type, et le code du moteur/des shells continue d'importer depuis ce chemin sans changement :

API du pontCe qu'elle fait
host.profilePrénom, e-mail, photo de profil, ville, etc. de l'utilisateur. Préremplit les entrées via bindToProfile.
host.assetsRequêtes de catalogue, résolution d'assets, UI de sélecteur fournie par l'hôte.
host.stateSauvegarde / chargement des emplacements d'entrées. IndexedDB sur le web, système de fichiers sur Tauri, mémoire sur la CLI.
host.clipboardÉcrit du texte ou une image dans le presse-papiers (avec repli selon la plateforme).
host.exportRastérise ou sérialise la cible de rendu. Applique le filigrane pour les outils expérimentaux.
host.netFetch en liste blanche - disponible uniquement si l'outil a déclaré la capacité "network". (Aucun outil livré ne l'utilise actuellement.)

Les surfaces optionnelles et additives n'apparaissent que lorsqu'un shell les fournit. Certaines sont conditionnées par une capacité - exposées uniquement quand l'outil déclare le drapeau correspondant : host.compose (intégrer le rendu d'un autre outil - compose), host.capture (capture de page pour URL Screenshot - capture) et host.recorder (capture micro/caméra/écran pour les outils d'enregistrement - microphone / camera / screen). Les autres sont détectées par fonctionnalité - présentes chaque fois que le shell peut les fournir, l'outil gardant un repli pour les shells qui ne le peuvent pas.

Quelques surfaces phares, pour montrer l'étendue - Host API documente chacune d'elles, et packages/core/src/host-v1.ts est le contrat lui-même :

SurfaceDepuisCe qu'elle ajoute
host.tokens1.0Tokens de design DTCG - les primitives propres à la marque
host.text1.0Texte-vers-chemin via HarfBuzz WASM (le flag de capacité wasm signale les outils qui en dépendent)
host.media1.4Images de caméra en direct pilotant le hook onFrame. Amélioration progressive, délibérément pas conditionnée par le flag camera - un tel outil fonctionne quand même comme un outil ordinaire d'image fixe
host.color1.40Mathématiques de couleur perceptuelles : ΔEOK, contraste WCAG et APCA, dégradés OKLab, seuils de classes, palettes catégorielles, schémas d'harmonie (1.60), mélange CSS Color 4 et cuisson de dégradés (1.68). Pur et synchrone - les shells rattachent le makeColorApi() du moteur plutôt que d'implémenter quoi que ce soit, donc ça ne peut pas diverger
host.images1.60Décoder / redimensionner / réencoder des octets sur l'appareil - le chemin de conversion (HEIC → JPEG, compression en WebP, réduction d'échelle). Livré dans le shell web comme une façade paresseuse, donc le décodeur HEIC n'entre jamais dans le chunk de démarrage
host.geom1.64Géométrie vectorielle exacte : booléens de chemins, décalage, contour-vers-remplissage, réduction de splines, simplification, détection de collision. Également pur, synchrone et rattaché depuis le moteur (makeGeomApi()) ; les échecs sont retournés, jamais levés

Le reste suit les mêmes règles et est documenté avec elles : pdf (1.8) et pptx (1.58) pour la chirurgie de documents sur l'appareil, audio (1.71) et speech (1.96) pour l'analyse de clips et la synthèse/transcription vocale sur l'appareil, viz (1.72) pour le contrat de remplacement MilkDrop, codec (1.100) et layers (1.102) pour la sortie en profondeur de bits et en bitmap par couches, upscale (1.101) et matte (1.103) pour les modèles sur l'appareil, raster (1.105) pour les hooks qui font leur propre travail de pixels, connectors (1.106) pour les flèches compatibles export et c2pa (1.85) pour signer des octets finis. Le nombre grandit ; les règles non.

Les capacités déclarables sont : network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, ajoutée en 1.54, est la capture d'écran via host.recorder - l'utilisateur choisit un écran/une fenêtre/un onglet dans l'UI native du navigateur ; distincte de capture, qui rastérise une URL que l'outil lui-même désigne.)

Le même outil tourne dans le navigateur, Tauri et la CLI headless car chaque shell implémente cette interface - l'outil ne sait jamais dans lequel il se trouve.

Le pont est versionné. Ajouter des méthodes est une version mineure. Supprimer ou modifier des signatures est un incrément de version majeure. Quand la v2 sortira, la v1 devra continuer de fonctionner.

4. Les ID d'assets sont éternels

suse/logo/primary est un contrat. Une fois publié :

Cela rend les états d'outils sauvegardés et les liens partagés par URL durables au fil des années.

5. Le mode URL est de premier ordre

Chaque entrée doit pouvoir s'exprimer comme un paramètre d'URL :

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

Ce lien à lui seul, sans rien d'autre, est l'asset fini signed by Lollyvector SVG55 paths~2.6k nodes38 groups60 KBVérifie par toi-mêmeRécupérer le fichier signéCe lien à lui seul, sans rien d'autre, est l'asset fini signed by Lollyvector SVG55 paths~2.6k nodes38 groups61 KBVérifie par toi-mêmeRécupérer le fichier signé

Le mode CLI est le mode URL sous un autre transport - le shell CLI construit un objet d'état URL à partir de argv et exécute le même pipeline moteur. Il n'y a qu'un seul chemin de rendu. La CLI ne peut pas diverger de la GUI parce que ce n'est pas une implémentation séparée.

url-mode.ts gère l'aller-retour (analyse et sérialisation). Un ensemble de paramètres réservés n'est jamais transmis à l'outil comme entrées : les contrôles de sortie (format, export, copy, filename, width/w, height/h, unit, dpi), les cadrans d'impression et de provenance (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) et les porteurs d'état (template, z - le jeton compacté « Lien le plus court » - et zx, le même chiffré avec un mot de passe). L'ensemble RESERVED dans engine/src/url-mode.ts fait autorité et est fixé par un test ; URL Mode documente chacun d'eux, y compris la poignée non listée ici. Les entrées de type asset en mode URL sont sérialisées par leur id ; le runtime les résout via host.assets.get() avant l'hydratation. width/height sont des valeurs dans unit (par défaut px, aussi mm/cm/in/pt/pc) ; avec une unité physique, dpi fixe la résolution raster. Ils définissent la taille du document du canvas et préremplissent le panneau de dimensions d'export.

Parce que chaque entrée voyage dans le lien, un changement de paramètre donne un asset fini différent. Toute cette palette n'est qu'une couleur de départ, une harmonie et un nombre de pas :

Neuf nuances sur quatre teintes, toutes issues de la seule couleur de départ portée par le lien signed by Lollyvector SVG10 groups25 KBVérifie par toi-mêmeRécupérer le fichier signéNeuf nuances sur quatre teintes, toutes issues de la seule couleur de départ portée par le lien signed by Lollyvector SVG10 groups25 KBVérifie par toi-mêmeRécupérer le fichier signé

6. Le stockage passe par le pont, jamais en direct

Web shell : IndexedDB. Tauri : système de fichiers. CLI : en mémoire. Les outils ne voient que host.state.save(slot, data) et host.state.load(slot). localStorage n'est pas utilisé - trop petit et incapable de stocker des blobs.

Les utilisateurs peuvent enregistrer plusieurs emplacements d'édition nommés par outil et retrouver chaque session plus tard. Aucune création de compte n'est requise ; l'état est propre à l'appareil. Comme le pont est le seul point de passage, cet état par appareil est aussi portable : shells/web/src/data-transfer.ts relit tout via host.profile/host.state/host.assets dans un unique zip lolly-backup qui s'importe sur n'importe quelle autre installation - la réponse hors ligne à "passer à un nouvel appareil" qui ne nécessite aucun serveur (spécification complète : docs/data-transfer.md). La synchronisation multi-appareils fonctionne déjà par-dessus cela, en envoyant le même bundle vers le stockage que la personne choisit (docs/sync.md).

7. Les étiquettes de maturité disent ce qu'est un outil

Chaque outil déclare status: official | community | experimental dans son manifeste. La galerie trie par statut. Les outils expérimentaux filigranent automatiquement leurs exports - le filigrane est appliqué par host.export.render, pas par l'outil, si bien qu'un auteur d'outil non officiel ne peut pas le désactiver.

C'est une réponse structurelle au risque de perception selon lequel chaque outil de la galerie porte le même poids. Quel que soit le processus qu'une équipe ajoute autour du catalogue, il vient s'ajouter par-dessus.

8. Les entrées d'outil sont typées via le manifeste, y compris les assets

Les entrées déclarent un type : text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table et file. L'hôte génère un contrôle générique par type à partir du manifeste - les outils n'écrivent aucun code de contrôle. (Le préremplissage depuis le profil de l'utilisateur n'est pas un type - toute entrée peut porter bindToProfile.) Trois pèsent plus que les autres :

9. Les templates sont sans logique (Handlebars, pas EJS)

Handlebars a été choisi plutôt qu'EJS délibérément :

La logique vit dans hooks.js, où elle est explicite et révisable. Assistants Handlebars disponibles : {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (plus les assistants de format de données icsStamp/rfcText/csvCell utilisés par les templates jumeaux .ics/.vcf/.csv).

10. Les outils composent des outils

Un outil peut intégrer le rendu d'un autre outil sans import d'outil à outil - la composition est résolue par le moteur, jamais par le code de l'outil. Il y a deux surfaces :

Composer le rendu de n'importe quel outil : un enfant SVG reste un vrai vecteur quand le parent exporte en SVG ou PDF, et se rastérise avec netteté pour PNG ; les enfants PNG/JPG/WEBP s'intègrent comme des images. Nécessite la capacité compose. Les enfants composés sont des intermédiaires - jamais filigranés ni estampillés de provenance - et la composition se dégrade avec élégance : un shell incapable de rendre un enfant omet simplement l'emplacement et le parent se rend quand même.


Ce que nous avons délibérément choisi de ne pas faire


Le cycle de vie d'un rendu

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

  1. Démarrage. Le shell web ouvre IndexedDB, construit le pont de capacités, synchronise les catalogues d'outils et d'assets (ou charge depuis le cache hors ligne).
  2. Routage. Hash de l'URL → vue tool, avec qr-code et les paramètres d'URL extraits.
  3. Chargement. loadTool('qr-code', fetchFile) récupère tool.json, le valide par rapport au schéma JSON, puis récupère template.html, styles.css et le source de hooks.js.
  4. Analyse de l'état d'URL. parseUrlState traduit les paramètres d'URL en valeurs d'entrée initiales. Les références d'assets (?logo=suse/logo/primary) sont analysées comme des objets légers { id, _unresolved: true }.
  5. Exécution. createRuntime(tool, host, initialValues) construit le modèle d'entrées (en fusionnant les données de profil, les valeurs par défaut et les valeurs initiales), résout les références d'assets via host.assets.get(), charge les hooks (host dans la portée de la closure, non isolé en bac à sable), et appelle hooks.onInit.
  6. Rendu. Le shell s'abonne au runtime ; à chaque changement d'état, il reçoit { model, hydrated }. Il affiche les contrôles d'entrée à partir du modèle et écrit le HTML du template hydraté dans #tool-canvas.
  7. Interaction. L'utilisateur saisit une valeur dans un champ → runtime.setInput(id, value) → application des contraintes → appel de hooks.onInput → réhydratation → nouveau rendu. Le canvas se met à jour en direct.
  8. Export. L'utilisateur clique sur Télécharger (PNG) → runtime.export(canvasNode, 'png') → host.export.render (rastérise via dom-to-image-more ; SVG/PDF passent par des vectoriseurs dédiés qui parcourent le DOM) → blob → host.export.download. L'éventail de formats qu'un outil peut choisir est large, et l'énumération render.formats dans schemas/tool.schema.json en fait foi - rasters et rasters flottants, vecteurs et fichiers de découpe, impression/CMYK, mouvement, documents éditables (pptx, docx, odt), palette et sorties de données/texte, fichiers audio et de polices. URL Mode nomme chaque identifiant et ce qu'il produit. L'audio figure dans cette énumération comme le reste (wav, mp3, m4a, opus, déclarés par l'audiogramme et les outils d'enregistrement) ; séparément, le mode render.capture d'un outil d'enregistrement pilote host.recorder, dont la prise arrive sous forme de Blob terminé, dans le conteneur choisi par le navigateur pour l'enregistrement. (Les outils qui définissent render.export: false - par exemple Color Palette, Countdown Timer, Strip Hidden Data, Text, Compress PDF - masquent les contrôles de téléchargement, de format et de dimensions.) Les unités physiques sont converties ici selon le format (PDF → points de page réels, raster → pixels au DPI avec un bloc pHYs). Les métadonnées d'auteur/provenance (auteur, outil, source - construites par engine/src/metadata.ts) sont intégrées selon le format : iTXt pour PNG, EXIF pour JPEG, dictionnaire info pour PDF, <metadata> pour SVG, commentaire pour GIF. Les outils expérimentaux reçoivent un filigrane ajouté par l'hôte, pas par l'outil.

Le panneau d'export qu'ouvre ?options : le couple nom de fichier/format, la taille de sortie et les contrôles qui écrivent le fichier signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBVérifie par toi-mêmeRécupérer le fichier signéLe panneau d'export qu'ouvre ?options : le couple nom de fichier/format, la taille de sortie et les contrôles qui écrivent le fichier signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBVérifie par toi-mêmeRécupérer le fichier signé

Même cycle de vie sous Tauri. Même cycle de vie en CLI - jsdom fournit le DOM headless ; la sortie va vers un fichier ou stdout.


Statut open source

Le code est sous licence MPL-2.0. engine/, shells/, services/, schemas/ et docs/*.ts sont open source sous MPL-2.0 - une plateforme d'échafaudage neutre vis-à-vis des fournisseurs pour l'outillage de marque, le tout dans un seul dépôt public, lolly-tools/lolly.

Le contenu des outils est livré sous forme de packs de marque, chacun avec ses propres conditions (voir le NOTICE.md du pack). community/ est un répertoire de ce dépôt et ses outils indépendants de toute marque sont eux aussi sous MPL-2.0. brands/suse/ est le pack privé suse-lolly, l'unique sous-module : les outils SUSE et le catalogue SUSE, propriété exclusive de SUSE, y compris sa musique PremiumBeat sous licence. brands/lolly-start/ est la marque de démarrage vierge que possède ce dépôt. Les polices sont livrées dans un pack sous la SIL Open Font License 1.1 - le pack SUSE contient les polices SUSE et SUSE Mono.

Il n'existe pas de répertoire tools/ ou catalog/ à la racine du dépôt. packages/node-shell/src/content-roots.ts répond à « où vit l'outil <id> » et « où est le catalogue » à partir de profiles.json au moment de la lecture, si bien qu'un profil est une réponse par processus et qu'aucune arborescence n'a besoin d'être assemblée au préalable. Une véritable paire tools/ + catalog/ n'est écrite que dans une sortie de build - dist/, un paquet RPM, une image de conteneur - parce qu'un navigateur récupère ces deux chemins via HTTP.

La séparation est appliquée - il n'y a aucune importation croisée depuis engine/ vers le contenu des outils - si bien que la frontière plateforme/contenu reste nette.


Où le moteur s'arrête et où l'hôte commence

Si tu peux le décrire en données pures + Handlebars → moteur. Si ça touche au DOM, au système de fichiers, au réseau ou à une API navigateur/OS quelconque → hôte.

La ligne est nette exprès. Le moteur est la partie open source. Tout ce qui connaît SUSE, des plateformes spécifiques ou des environnements d'exécution en reste dehors.

Pour le niveau de détail suivant, engine/README.md énumère chaque module du moteur et sa responsabilité, et Modèle de menace et frontières de confiance consigne où cette même ligne fait aussi office de frontière de confiance.