Questo documento riassume lo scopo, la struttura e le decisioni architetturali della piattaforma Lolly. Riflette sia la visione del prodotto sia lo stato attuale del codice.
Stato: Lolly è rilasciato. La versione 1.0 è uscita come open source con licenza MPL-2.0 il 30 agosto 2026, e funzionalità, impostazioni predefinite e catalogo degli strumenti continuano a cambiare tra un rilascio e l'altro. Il motore è deterministico, con un solo percorso di rendering dietro ogni shell. La sua sicurezza non ha ancora avuto un audit indipendente, e le prove di adozione risalgono a pochi mesi fa. Vedi Adozione e Governance per lo stato attuale e come viene misurata l'adozione.
Come leggere questa pagina. Contiene due tipi di materiale, in ordine. La prima metà spiega perché esiste: il problema, il posizionamento e il ciclo di vita che attraversa un singolo asset. Da Il quadro d'insieme in poi si tratta di come si incastrano i livelli: il documento di architettura per chi contribuisce, che copre la separazione motore/shell/pacchetto, la struttura del repository, gli obiettivi di distribuzione e gli impegni che vincolano ogni modifica alla piattaforma. Se sei qui per modificare il codice anziché per capire il prodotto, inizia dal quadro d'insieme.
Due documenti complementari approfondiscono più di questa pagina.
engine/README.mdnel repository è la mappa del motore modulo per modulo, con una tabella generata di ogni modulo e di cosa analizza o scrive. Modello di minaccia e confini di fiducia è la stessa architettura letta in termini di confini di fiducia, ed è la pagina giusta per qualsiasi domanda su cosa il motore considera non attendibile.
Perché esiste
Il lavoro creativo ripetibile è troppo prevedibile per giustificare mani esperte ogni volta, ed è troppo sensibile alla qualità per essere delegato senza vincoli. Se lasciato a sé stesso, va in uno di tre modi: lento, incoerente o vincolato ai template di un fornitore.
Questa piattaforma è la risposta diretta:
Contenuti e creatività programmatici su larga scala - asset generati dagli input, con le regole impostate una volta, per chiunque ne abbia bisogno.
Lolly non è il posto dove nasce un design system - è il posto dove viene prodotto. Pensalo come un distributore automatico per il design: fai una selezione, ottieni un risultato. Ogni volta. Il motore lavora per la massima qualità che ogni formato può produrre sull'hardware che hai davanti, e lo stesso motore crea lo stesso file su ogni piattaforma su cui viene distribuito.
Il risultato è abbondanza: ogni evento ha la segnaletica corretta, ogni avviso CVE rispetta lo stile della casa, ogni etichetta si stampa pulita, ogni firma email è aggiornata - tutto grazie a strumenti che già portano le regole. La piattaforma gestisce la creatività ricorrente e operativizzata. Deliberatamente non è uno strumento creativo su misura - i designer continuano a possedere il lavoro di punta.
Innova in modo probabilistico, scala in modo deterministico
Ogni discussione sull'IA in una pipeline creativa si arena sulla stessa domanda: quale parte di questo è compito della macchina? È una domanda antica con una risposta consolidata. Amanuensi e miniaturisti già lavoravano tra due strumenti - lo schizzo libero, dove nulla era fissato e tutto poteva essere provato, e la stampa a caratteri mobili, intimidatoria proprio perché si impegnava. Gli schizzi erano dove nasceva l'arte. La stampa era il modo in cui raggiungeva chiunque. Nessuno confondeva i due, ed entrambi continuavano a progredire - nuovi inchiostri, nuovi caratteri, nuove presse - migliorando ciascuno in armonia con l'arte e l'intento che servivano.
Lolly traccia la stessa linea. Esplora in modo probabilistico: un modello, un designer, un'idea abbozzata, un prompt che va da qualche parte che nessuno aveva pianificato. Poi scala in modo deterministico - ciò che diventa molti output è uno strumento, e uno strumento si renderizza allo stesso modo ogni volta a partire da input che puoi leggere. L'esplorazione resta libera perché nulla a valle dipende dal fatto che approdi due volte nello stesso modo. L'output guadagna fiducia perché non è un'ipotesi. Portare la sperimentazione con l'IA verso risultati prevedibili e riproducibili non è una disciplina nuova; è la stessa divisione del lavoro che ha reso affidabile il lavoro a stampa fin dall'inizio.
Fidati del processo creativo, scala con rigore.
Contro le alternative
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 |
Completezza delle capacità tra gli strumenti creativi odierni, ricercata ad agosto 2026. Punteggio: 0 assente, 25 livello soluzione di ripiego, 50 reale ma limitato o parziale, 75 solido con avvertenze, 100 competenza centrale.
signed by Lollypositioning-comparison.htmlHTMLpixels, not shapes40 KBAI generatedgenerated by GPT-6Verifica tu stessoScarica il file firmatoIl divario è evidente: nulla di ciò che è oggi disponibile offre output prima-vincoli, capace di funzionare offline, a basso livello di competenza e accessibile internamente. Lolly include persino una tela aperta - Design - dove colori, tipografia e asset si conformano ai globali del brand, così l'organizzazione libera resta prima-vincoli. Ciò che non è, è una suite di design non vincolata: i designer continuano a usare Illustrator e Figma per il lavoro di punta su misura. Le permutazioni possono essere assemblate con questo strumento.
signed by Lollyvector SVG367 paths~62k nodes773 groups3 images1453 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG367 paths~62k nodes776 groups3 images1454 KBVerifica tu stessoScarica il file firmato
Usalo per: Generazione rapida di asset creativi operativizzati - riquadri per eventi, badge nominativi, firme, avvisi CVE, codici QR, card social, etichette di spedizione, report strutturati.
Non usarlo per: Contenuti hero su misura.
Il ciclo di vita di una campagna
Il modo più chiaro per vedere cos'è Lolly non è un elenco di funzionalità - è seguire un singolo asset mentre passa di mano in mano. Osserva una card di campagna localizzata mentre attraversa l'organizzazione:
- Il creativo stabilisce le regole. Un designer crea il template di base nello strumento Design, codificando la tipografia e le variabili di colore del brand. Non sta creando una sola card - sta facendo il lavoro fondamentale una volta sola per non doverla mai più localizzare a mano.
- Lo sviluppatore lo scala. Lo stesso template viene collegato a una pipeline notturna tramite la CLI, così un nuovo grafico o una nuova variante linguistica viene generata automaticamente - nessun designer riapre il file.
- Il produttore semplicemente lo usa. Un rappresentante di vendita, offline su un aereo, apre lo stesso strumento e genera un deck perfettamente in linea con il brand per un incontro con un cliente. Nessuna competenza di design, nessuna rete, nessuna attesa.
Il "nuovo grafico" del secondo passaggio è un rendering come questo, prodotto da una stringa di dati e da alcuni parametri senza che nessuno apra un file di design:
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBVerifica tu stessoScarica il file firmato
Il punto non è che Lolly sia buono per i designer e buono per gli sviluppatori e buono per le vendite, ciascuno nel vuoto. È una staffetta: il lavoro iniziale del creativo viene scalato dallo sviluppatore, che a sua volta abilita il produttore. L'esperienza senza sforzo per il rappresentante non tecnico sull'aereo è possibile solo grazie al rigore fissato dal designer e implementato dallo sviluppatore.
Questo è il moltiplicatore di forza. Lolly non è un cassetto di strumenti separati per ruoli separati - è un unico ciclo di vita deterministico dell'asset che ogni ruolo tocca, e ogni passaggio di mano moltiplica il valore del precedente.
Uno strumento, molti output
Le regole del brand vivono nello strumento, non in ogni file che produce (vedi Come si confronta Lolly). Sistema bene lo strumento una volta e ogni output eredita lo stesso carattere, colore e spaziatura, che si tratti di una singola card o di un foglio di calcolo con righe in una dozzina di lingue. Come controlli il tuo lavoro, e chi lo fa, resta una tua scelta; Lolly rende più piccola la cosa da controllare e più veloce da produrre l'output.
Lo stesso strumento deterministico raggiunge quella scala in tre modi, tutti producendo lo stesso output identico:
- Una persona, nell'app. La griglia batch
/pro: incolla o importa le righe, ottieni un asset finito per riga, scarica lo zip. Nessuna competenza di design, nessuna attesa. - Uno sviluppatore, dalla riga di comando. La CLI esegue lo stesso motore e lo stesso percorso di rendering in modalità headless, così lo strumento può essere sequenziato su ogni riga in uno script o in una pipeline notturna. Una chiamata
lolly <tool> --field=…in un ciclo è l'intera integrazione. - Un sistema o un agente IA, tramite MCP. Lo stesso strumento azionato in modo programmatico, alla stessa fedeltà, per tutte le righe che il lavoro richiede.
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBVerifica tu stessoScarica il file firmato
Un insieme di vincoli di brand, fissato una volta da un designer; tre percorsi verso lo stesso output identico.
Il quadro d'insieme: come si incastrano i livelli
Tutto da qui in poi è architettura. Il diagramma è l'intero sistema in un'unica vista: gli strumenti sono dati in alto, il motore al centro non conosce nulla di alcuna piattaforma, le shell sotto di esso implementano un unico contratto, e i cataloghi forniscono il contenuto.
┌─────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────┘Struttura del repository
Lolly è un unico repository. engine/, schemas/, scripts/, tests/, api/, docs/, community/, brands/lolly-start/, ogni shells/ ed entrambi i services/ sono semplici directory al suo interno. L'unica eccezione è brands/suse, un submodule git privato che contiene il pacchetto di strumenti e il catalogo SUSE, opzionale e assente da un clone pubblico. Quali pacchetti legge una determinata build è un content profile (profiles.json), risolto per processo anziché commutato globalmente. Vedi Guida alla build » Ottenere i sorgenti per il comando di clone e per come si esegue il commit di una modifica all'interno del pacchetto privato.
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 + positioningModello di distribuzione della piattaforma
La piattaforma funziona su diverse superfici - PWA web, desktop/mobile Tauri, la CLI scriptabile e la TUI interattiva. Tutte usano lo stesso motore e gli stessi file degli strumenti.
Web (PWA) - distribuzione principale
Ospitata su un URL controllato da SUSE. Funziona offline una volta che il service worker ha memorizzato nella cache strumenti e asset. È qui che la maggior parte di dipendenti, fornitori e partner userà la piattaforma. Nessun account richiesto - lo stato è memorizzato in IndexedDB per dispositivo.
La shell web è responsive a partire da un unico layout. Su desktop uno strumento è una barra laterale di controlli ridimensionabile accanto a un piano di anteprima con navigazione della tela nativa per trackpad (Cmd/Ctrl-rotellina o pizzico per zoomare intorno al cursore, trascinamento con Spazio o con il tasto centrale per spostarsi, i tasti 0/1/+/− e un HUD Adatta/%). Su mobile (≤640px) i controlli diventano un foglio ancorato in alto con una maniglia trascinabile che si aggancia a sguardo/metà/pieno (il tocco commuta) sopra un'anteprima statica a schermo intero, e un pulsante flottante Render apre i controlli di Esportazione in un popup a foglio inferiore. Il tocco offre pizzico per zoomare e trascinamento per spostarsi sull'anteprima. Il percorso di rendering e i controlli di esportazione sono identici in entrambi i casi - solo l'interfaccia si riorganizza.
signed by Lollyvector SVG131 paths~6.1k nodes158 groups1 image142 KBVerifica tu stessoScarica il file firmato
Lo stesso strumento in larghezza telefono, senza un secondo layout da mantenere: i controlli diventano un foglio in alto, l'anteprima occupa tutto lo schermo e la pillola di rendering fluttua sopra.
signed by Lollyvector SVG97 paths~3.3k nodes113 groups99 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG97 paths~3.3k nodes113 groups100 KBVerifica tu stessoScarica il file firmato
Modalità batch (/pro). La shell web include anche una griglia batch in stile foglio di calcolo (shells/web/src/pro/) che renderizza molte righe insieme su uno o più strumenti. Gestisce round-trip CSV/TSV più incolla da foglio di calcolo, template/formato/dimensione/unità/dpi per riga, un pannello laterale editor di blocchi con anteprima live, colonne di export comprimibili, una barra di tag "rilevanza" per riga, riordino righe con maniglia di trascinamento a sinistra, conferma di eliminazione in due passaggi, sessioni batch salvate e download in .zip. È la superficie uno-a-molti dietro il posizionamento "generazione di contenuti di massa".
Tauri desktop / mobile
App nativa pacchettizzata (footprint ridotto grazie a Tauri). Offre piena disponibilità offline, accesso al filesystem per gli strumenti che dipendono dalla CLI (PDF Smasher, Font Outliner) e accesso alla fotocamera. Prevista per un potenziamento degli strumenti a metà 2026.
CLI
lolly <tool-id> [--input=value ...] --output=file.png
Gli utenti desktop possono richiamare molti strumenti dal terminale. La shell CLI carica lo stesso motore, crea un DOM jsdom, esegue lo stesso percorso di rendering e scrive il file. La URL mode è il trasporto - la CLI non è un'implementazione separata. Questo garantisce che gli output di CLI e GUI siano identici.
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 toolTUI
pnpm run tui
La controparte interattiva della CLI: un'app da terminale a schermo intero e keyboard-first (costruita su Ink) per sfogliare gli strumenti, compilare gli input, salvare progetti ed esportare - tutto senza GUI. Il suo host bridge riutilizza l'implementazione della CLI per i formati DOM-free (SVG/EMF/EPS/HTML + testo/dati), e aggiunge stato su disco sotto ~/.lolly più un'anteprima inline opzionale. Oltre a questo ha un livello di rendering via browser: un Chromium headless dedicato (lo stesso installato dal server MCP) che produce raster/PDF/video e cattura di URL live su richiesta - guidando una copia buildata della shell web così che l'output sia identico, e avviandosi solo al primo export di un formato del genere. Così url-shot (con crop + ricolorazione + PDF/SVG vettoriale) e ogni strumento raster/pdf funzionano anche nel terminale. Vedi la guida TUI.
Su qualunque superficie ti trovi, la scheda Capabilities della dashboard è la mappa completa di ciò che la piattaforma dichiara di saper fare, raggruppata e leggibile senza aprire un solo strumento.
Categorie di strumenti
Gli strumenti sono etichettati con una category nel loro manifest per il raggruppamento nella galleria.
Le righe sono elencate nell'ordine delle sezioni della galleria. La sezione utility viene sempre renderizzata per ultima nella galleria (dopo ogni altra categoria, incluse quelle future) - è il cassetto "Offline Utilities" on-device.
| Categoria | Esempi | Pianificato |
|---|---|---|
everyone | QR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence, Record | Employee Image Stationery |
designer | Brand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, Booklet | Font Outliner |
event | Meeting Planner, Event Name Badge, Wayfinding Signage, Calendar ICS, Booth Studio | Event Stationery, Bulk Name Badges, Room Agenda Cards |
product | - | CVE Alert, Product Release Announcement, Blog OG Image |
utility | Strip Hidden Data, Text, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL Screenshot | Convertitori di unità/formato, altre utility per la privacy on-device |
Quelle celle sono esempi, non inventari. Quali strumenti esistano è una proprietà del profilo che hai montato, non di questa pagina: un pacchetto brand aggiunge i propri, e può escludere uno strumento community che preferisce non distribuire. catalog/tools/index.json - generato dai manifest, ed è il registro che la galleria legge davvero - è la lista autorevole; per contare cosa monta un profilo, conta i manifest (ls community//tool.json brands//tools/*/tool.json) invece di fidarti di un numero scritto qui. (Un id di strumento presente in due pacchetti viene montato una sola volta, dal pacchetto vincente.)
Gli strumenti sono anche classificati per stato: official (approvato dal brand, senza watermark), community (contributo esterno), experimental (export con watermark). Gran parte della libreria è official; gli studio più recenti e gli strumenti di cattura tendono a stare su community o experimental mentre si consolidano. Ogni superficie mostra il badge, così chi legge sa cosa sta prendendo prima di aprirlo - e, come le celle delle categorie sopra, l'appartenenza per stato cambia troppo in fretta per essere elencata qui. Leggila dalla galleria o dall'indice generato.
Design è il primo strumento costruito sulla modalità canvas libero render.layout: "editor" - una superficie senza chrome a manipolazione diretta dove trascini, ridimensioni, ruoti e agganci box di testo, forme e immagini, poi esporti attraverso lo stesso percorso di rendering di ogni altro strumento.
Strip Hidden Data è la prima utility on-device (privacy: "on-device"): uno strumento di trasformazione dei contenuti che prende un file fornito da te, lo elabora interamente nel browser e restituisce una copia pulita - mai caricata, mai filigranata, senza alcuna provenienza applicata. Text è la seconda - un banco di lavoro on-device per le operazioni quotidiane di incolla-e-usa su un sito web (formattazione JSON, decodifica JWT, Base64, codifica/decodifica URL, hashing SHA). Compress PDF è la terza - riduce un PDF ricomprimendone le immagini, anche in questo caso interamente on-device. Il marcatore e il testo del suo badge "Viene eseguito sul tuo dispositivo - niente viene caricato" coprono ora l'intero insieme di trasformazioni: Strip Hidden Data, Text, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (distrugge regioni di un'immagine, SVG o PDF), Prompt Card e Rebrand (ricambia il tema di un .pptx sul posto) dove il profilo lo monta. Questa è una categoria di utility per la privacy che sostituisce la consegna di file riservati a siti web monofunzione.
signed by Lollyvector SVG124 paths~29k nodes324 groups395 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG124 paths~29k nodes324 groups396 KBVerifica tu stessoScarica il file firmato
Nota:
categoryestatussono denormalizzati incatalog/tools/index.json(il registro che la gallery legge) a partire da ognitool.json. Il manifest è la fonte di verità - l'indice viene generato dapnpm run build:catalogepnpm run validate:catalogfa fallire la CI se l'indice committato diverge dai manifest.
Impegni architetturali
Queste decisioni sono definitive. Cambiarne una qualsiasi è un'impresa importante - condizionano ogni altra decisione nel codebase.
1. Strumenti dichiarativi, con una via di fuga imperativa
Uno strumento è un manifest (tool.json) + un template (template.html) + hooks.js opzionale.
Il manifest dichiara gli input. Non il template. Gli input non vengono dedotti dai token Handlebars. Il manifest è il contratto; il template consuma variabili con nome tramite {{id}}.
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBVerifica tu stessoScarica il file firmato
Gli hook sono opzionali. La maggior parte degli strumenti è puramente dichiarativa - manifest + template bastano. Gli strumenti che richiedono valori calcolati (codifica QR, formattazione dati dei grafici) forniscono hooks.js che espone funzioni di ciclo di vita con nome (onInit, onInput, onFrame - l'hook per frame della fotocamera live per strumenti motion-reactive - onLevel, beforeExport, afterExport, exportFile - il percorso di trasformazione file-in/file-out usato dalle utility on-device come Strip Hidden Data - e exportStill, per uno strumento che gestisce il proprio raster profondo). L'host carica gli hook tramite new Function('host', …) con il capability bridge iniettato come closure scope. Questo è un contratto di portabilità, non una sandbox di sicurezza: gli hook girano comunque nel realm della pagina e possono raggiungere window/fetch/document in una shell browser - host. è la superficie supportata e portabile, non un confine imposto. I risultati degli hook asincroni sono a tempo (onInit 5s, onInput 2s, beforeExport/afterExport 5s, exportFile/exportStill 10s) e i risultati tardivi vengono scartati; un hook sincrono* fuori controllo non può essere prelazionato. Il codice hook di terze parti non fidato non è quindi sicuro da eseguire finché non arriverà l'isolamento tramite Worker.
Questo conta perché: gli strumenti dichiarativi possono essere scritti da non sviluppatori. Se ogni strumento fosse una web app, la nota di rischio "competenze limitate per creare/mantenere template workhorse" diventerebbe un collo di bottiglia permanente.
2. Strumenti e asset sono dati, non codice pacchettizzato
Le app web e Tauri recuperano i cataloghi di strumenti e asset da un URL noto all'avvio, li mettono in cache localmente e operano su ciò che c'è. Aggiungere una nuova tile evento o un asset stagionale non richiede una release dell'app.
I byte degli asset hanno checksum SHA-256 per prevenire il poisoning del CDN. id + version dell'asset guidano l'invalidazione della cache.
3. Il Capability Bridge è l'unica API che gli strumenti vedono
Gli strumenti non toccano mai il DOM al di fuori della loro area template, non chiamano mai fetch direttamente, non leggono mai il filesystem. Chiamano metodi host.* versionati. La definizione canonica del contratto è packages/core/src/host-v1.ts - l'SDK per autori di strumenti @lolly-tools/core, così una terza parte può costruirci sopra senza dipendere dal motore; engine/src/bridge/host-v1.ts ne è una re-esportazione di tipo, e il codice del motore/delle shell continua a importare da quel percorso senza modifiche:
| API del bridge | Cosa fa |
|---|---|
host.profile | Nome, email, foto profilo, città ecc. dell'utente. Pre-compila gli input tramite bindToProfile. |
host.assets | Query sul catalogo, risoluzione degli asset, UI di selezione fornita dall'host. |
host.state | Salva / carica slot di input. IndexedDB su web, filesystem su Tauri, memoria su CLI. |
host.clipboard | Scrive testo o immagine negli appunti (con fallback per piattaforma). |
host.export | Rasterizza o serializza il target di rendering. Applica il watermark per gli strumenti experimental. |
host.net | Fetch con allowlist - disponibile solo se lo strumento ha dichiarato la capability "network". (Nessuno strumento in distribuzione la usa attualmente.) |
Le superfici opzionali e additive compaiono solo quando una shell le fornisce. Alcune sono gated per capability - esposte solo quando lo strumento dichiara il flag corrispondente: host.compose (incorpora il rendering di un altro strumento - compose), host.capture (cattura pagina per URL Screenshot - capture) e host.recorder (cattura microfono/fotocamera/schermo per gli strumenti di registrazione - microphone / camera / screen). Le altre sono feature-detected - presenti ogniqualvolta la shell può fornirle, con lo strumento che mantiene un fallback per le shell che non possono.
Una manciata di superfici principali, per mostrare cosa copre - Host API documenta ognuna, e packages/core/src/host-v1.ts è il contratto stesso:
| Superficie | Da | Cosa aggiunge |
|---|---|---|
host.tokens | 1.0 | Token di design DTCG - le primitive proprie del marchio |
host.text | 1.0 | Testo-a-tracciato tramite HarfBuzz WASM (il flag di capacità wasm contrassegna gli strumenti che ne dipendono) |
host.media | 1.4 | Fotogrammi camera dal vivo che pilotano l'hook onFrame. Miglioramento progressivo, deliberatamente non vincolato dal flag camera - un tale strumento funziona comunque come un normale strumento per immagini statiche |
host.color | 1.40 | Matematica del colore percettiva: ΔEOK, contrasto WCAG e APCA, rampe OKLab, soglie di classe, palette categoriche, schemi di armonia (1.60), miscelazione CSS Color 4 e cottura dei gradienti (1.68). Puro e sincrono - le shell collegano il makeColorApi() del motore invece di implementare qualcosa, quindi non può divergere |
host.images | 1.60 | Decodifica / ridimensiona / ricodifica byte sul dispositivo - il percorso di conversione (HEIC → JPEG, compressione in WebP, riduzione di scala). Distribuito nella shell web come facciata pigra, così il decodificatore HEIC non entra mai nel chunk di avvio |
host.geom | 1.64 | Geometria vettoriale esatta: booleani di tracciati, offset, da contorno a riempimento, riduzione di spline, semplificazione, rilevamento delle collisioni. Anch'esso puro, sincrono e collegato dal motore (makeGeomApi()); i fallimenti vengono restituiti, mai sollevati |
Il resto segue le stesse regole ed è documentato insieme a esse: pdf (1.8) e pptx (1.58) per la chirurgia di documenti on-device, audio (1.71) e speech (1.96) per l'analisi delle clip e TTS/trascrizione on-device, viz (1.72) per il contratto placeholder MilkDrop, codec (1.100) e layers (1.102) per output deep-bit e bitmap a livelli, upscale (1.101) e matte (1.103) per i modelli on-device, raster (1.105) per hook che fanno da soli il lavoro sui pixel, connectors (1.106) per frecce export-safe e c2pa (1.85) per firmare byte finiti. Il conteggio cresce; le regole no.
Le capability dichiarabili sono: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, aggiunta nella 1.54, è cattura dello schermo tramite host.recorder - l'utente sceglie uno schermo/finestra/scheda nella UI nativa del browser; distinta da capture, che rasterizza un URL indicato dallo strumento stesso.)
Lo stesso strumento gira su browser, Tauri e CLI headless perché ogni shell implementa questa interfaccia - lo strumento non sa mai in quale si trova.
Il bridge è versionato. Aggiungere metodi è una versione minor. Rimuovere o cambiare firme è un bump di versione major. Quando uscirà v2, v1 dovrà continuare a funzionare.
4. Gli ID degli asset sono per sempre
suse/logo/primary è un contratto. Una volta pubblicato:
- L'ID non cambia mai, non viene mai riutilizzato.
- Cambi ai byte → incrementa
versionnel manifest. - Sostituito da un nuovo asset → imposta
deprecated: truee opzionalmentereplacedBy. - I riferimenti esistenti si risolvono sempre.
Questo rende gli stati salvati degli strumenti e i link condivisi via URL durevoli negli anni.
5. La URL mode è di prima classe
Ogni input deve essere esprimibile come parametro URL:
lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H signed by Lollyvector SVG55 paths~2.6k nodes38 groups60 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG55 paths~2.6k nodes38 groups61 KBVerifica tu stessoScarica il file firmato
La modalità CLI è la URL mode sotto un trasporto diverso - la shell CLI costruisce un oggetto di stato URL a partire da argv ed esegue la stessa pipeline del motore. C'è un solo percorso di rendering. La CLI non può divergere dalla GUI perché non è un'implementazione separata.
url-mode.ts gestisce il round-trip (parsing e serializzazione). Un insieme di parametri riservati non viene mai inoltrato allo strumento come input: i controlli di output (format, export, copy, filename, width/w, height/h, unit, dpi), i quadranti di stampa e provenienza (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) e i portatori di stato (template, z - il token compattato "Shortest link" - e zx, lo stesso cifrato con una password). L'insieme RESERVED in engine/src/url-mode.ts è l'autorità ed è fissato da un test; URL Mode documenta ognuno di essi, inclusa la manciata non elencata qui. Gli input di tipo asset in URL mode vengono serializzati tramite il loro id; il runtime li risolve via host.assets.get() prima dell'idratazione. width/height sono valori in unit (predefinito px, anche mm/cm/in/pt/pc); con un'unità fisica dpi imposta la risoluzione raster. Impostano la dimensione del documento canvas e pre-compilano il pannello delle dimensioni di export.
Poiché ogni input viaggia nel link, un cambio di parametro è un asset finito diverso. Questa intera palette è un solo colore seme, un'armonia e un numero di passi:
signed by Lollyvector SVG10 groups25 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG10 groups25 KBVerifica tu stessoScarica il file firmato
6. L'archiviazione passa dal bridge, non diretta
Web shell: IndexedDB. Tauri: filesystem. CLI: in memoria. I tool vedono solo host.state.save(slot, data) e host.state.load(slot). localStorage non è usato - è troppo piccolo e non può contenere blob.
Gli utenti possono salvare più slot di modifica con nome per ogni tool e tornare a ogni sessione in seguito. Non è richiesta la creazione di un account; lo stato è per dispositivo. Poiché il bridge è l'unico punto di passaggio, quello stato per dispositivo è anche portabile: shells/web/src/data-transfer.ts rilegge tutto tramite host.profile/host.state/host.assets in un unico zip lolly-backup che si importa su qualsiasi altra installazione - la risposta offline a "passa a un nuovo dispositivo" che non richiede un server (specifica completa: docs/data-transfer.md). La sincronizzazione multi-dispositivo funziona già sopra questa base, inviando lo stesso pacchetto allo storage scelto dalla persona (docs/sync.md).
7. I tag di maturità dicono cos'è uno strumento
Ogni tool dichiara status: official | community | experimental nel proprio manifest. La galleria ordina per status. I tool sperimentali filigranano automaticamente i propri export - la filigrana è applicata da host.export.render, non dal tool, quindi non può essere disattivata da un autore di tool non ufficiale.
Questa è una risposta strutturale al rischio di percezione secondo cui ogni tool nella galleria porta lo stesso peso. Qualsiasi processo che un team costruisca intorno al catalogo si aggiunge sopra di esso.
8. Gli input dei tool sono tipizzati tramite il manifest, asset inclusi
Gli input dichiarano un type: text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table e file. L'host renderizza un controllo generico per ogni tipo a partire dal manifest - i tool non scrivono codice di controllo. (Il pre-riempimento dal profilo utente non è un tipo - qualsiasi input può portare bindToProfile.) Tre pesano più degli altri:
asset(confiltereallowUpload) è il ponte verso il sistema di asset globale;allowUpload: falseè la leva di applicazione del brand per cose come i loghi delle tile di sponsorizzazione, dove sono ammessi solo asset di libreria. I caricamenti dell'utente usano la stessa formaAssetRefdegli asset di libreria, quindi i tool li gestiscono in modo identico.blocksè un gruppo di campi ripetuto - una mini-tabella dentro un unico input, modificata in un pannello laterale, con un menu di aggiunta tipizzato/discriminato e campi asset per blocco. Cliccare un blocco renderizzato sul canvas mette a fuoco la riga di quel blocco. Usato dameeting-planner,chart-creator,event-name-badge,wayfinding-signage,color-blockedigi-ad.vectorraggruppa un insieme fisso di numeri (ad esempio una trasformazione) in un unico controllo composto;filecontiene il file dell'utente stesso come byte in memoria per utilità di trasformazione on-device (ad esempiostrip-dataecompress-pdf).
9. I template sono senza logica (Handlebars, non EJS)
Handlebars è stato scelto rispetto a EJS deliberatamente:
- Senza logica. I template possono essere scritti da non sviluppatori.
- Sicuro per default.
{{x}}esegue l'escape HTML;{{{x}}}è raw solo se esplicitamente richiesto. - Nessun JS arbitrario nei template significa nessuna superficie di audit XSS per template.
La logica vive in hooks.js, dove è esplicita e revisionabile. Helper Handlebars disponibili: {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (più gli helper di formato dati icsStamp/rfcText/csvCell usati dai template affiancati .ics/.vcf/.csv).
10. I tool compongono tool
Un tool può incorporare il render di un altro tool senza import tra tool - la composizione è risolta dal motore, mai dal codice del tool. Ci sono due superfici:
- Manifest dichiarativo -
composes: [{ id, tool, inputs, format?, width?, height? }]. Il motore renderizza il figlio nominato e posiziona il risultato nel template senza logica come{{asset <id>}}.event-name-badgecompone oggiqr-codecome SVG. - URL di embed portabile -
<img src="https://lolly.tools/tool/<id>.<ext>?<inputs>">. La shell renderizza quel figlio localmente (un pixel segnaposto viene mostrato finché il render locale non si risolve); nulla viene mai recuperato dalolly.tools.
Componi il render di qualsiasi tool: un figlio SVG resta un vero vettore quando il genitore esporta in SVG o PDF e viene rasterizzato in modo nitido per PNG; i figli PNG/JPG/WEBP vengono incorporati come immagini. Richiede la capability compose. I figli composti sono intermedi - mai filigranati né marcati con provenienza - e la composizione degrada in modo controllato: una shell che non può renderizzare un figlio omette semplicemente lo slot e il genitore viene comunque renderizzato.
Cosa abbiamo scelto esplicitamente di non fare
- Niente EJS / niente JS arbitrario nei template. La superficie XSS è zero. La logica vive in
hooks.js. - Nessun CMS asset obbligatorio. I singoli utenti importano i propri file creativi direttamente in Risorse nell'app (Risorse e il Brand Studio) - nessun server, nessuna console di amministrazione. Il lavoro viene passato come sessione: un link di condivisione porta con sé i suoi input e le sue impostazioni (i file caricati viaggiano in un
.lolly), e la stessa sessione viaggia in un backup o durante una sessione di collaborazione. Chi controlla il deployment può poi bloccare una sessione condivisa come template - apre il link, registra i suoi valori come voce template nella directory di quello strumento nel brand pack e fa il commit - dopodiché compare nel selettore "New from template" dello strumento ed è raggiungibile con link diretto come?template=<id>. Git è il passo di blocco di chi possiede il deployment, mai del creatore. Per un catalogo condiviso e governato, un'organizzazione può gestire la directory degli asset allo stesso modo e vincolare gli aggiornamenti tramite revisione delle PR - un modello di governance disponibile, non un requisito dell'app. - Nessun RBAC forzato. L'app aperta è ad accesso pubblico per impostazione predefinita; il rischio per il brand è gestito con tag di maturità e filigrane. Un'organizzazione che vuole un controllo più stretto aggiunge sopra la propria autenticazione e il catalogo con revisione git di cui sopra.
- Nessun database centrale. Tutto lo stato utente è per dispositivo; la sincronizzazione opzionale lo copia nello storage scelto dalla persona, mai in un database Lolly.
- Nessun percorso di codice condiviso per strumenti/motore. Il motore è open source, così come gli strumenti brand-agnostici in
community/; un brand pack come il privatobrands/suse/porta i propri strumenti e catalogo secondo i propri termini. In entrambi i casi la separazione è applicata (nessuna importazione incrociata daengine/verso il contenuto degli strumenti) così la divisione resta pulita.
Il ciclo di vita di un render
Un utente apre lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H:
- Avvio. La web shell apre IndexedDB, costruisce il capability bridge, sincronizza i cataloghi di strumenti e asset (oppure carica dalla cache quando è offline).
- Routing. Hash dell'URL → vista
tool, conqr-codee i parametri URL estratti. - Caricamento.
loadTool('qr-code', fetchFile)recuperatool.json, lo valida rispetto allo JSON Schema, recupera il sorgente ditemplate.html,styles.cssehooks.js. - Analisi dello stato URL.
parseUrlStatetraduce i parametri URL in valori di input iniziali. I riferimenti agli asset (?logo=suse/logo/primary) vengono analizzati come oggetti leggeri{ id, _unresolved: true }. - Runtime.
createRuntime(tool, host, initialValues)costruisce il modello di input (unendo i dati del profilo, i valori predefiniti e i valori iniziali), risolve i riferimenti agli asset tramitehost.assets.get(), carica gli hook (conhostlegato alla closure, non sandboxato), chiamahooks.onInit. - Rendering. La shell si sottoscrive al runtime; a ogni cambiamento di stato riceve
{ model, hydrated }. Renderizza i controlli di input a partire dal modello e scrive l'HTML del template idratato in#tool-canvas. - Interazione. L'utente digita in un input →
runtime.setInput(id, value)→ vengono applicati i vincoli → viene chiamatohooks.onInput→ re-idratazione → nuovo rendering. Il canvas si aggiorna in tempo reale. - Esportazione. L'utente clicca Download(PNG) →
runtime.export(canvasNode, 'png')→host.export.render(rasterizza tramite dom-to-image-more; SVG/PDF passano attraverso vettorizzatori dedicati che percorrono il DOM) → blob →host.export.download. La gamma di formati a cui uno strumento può aderire è ampia, e l'enumrender.formatsinschemas/tool.schema.jsonne è l'autorità - raster e float raster, vettori e file di taglio, stampa/CMYK, movimento, documenti modificabili (pptx,docx,odt), palette e output dati/testo, file audio e font. URL Mode elenca ogni id e cosa produce. L'audio fa parte di quell'enum come qualsiasi altra cosa (wav,mp3,m4a,opus, dichiarati dall'audiogram e dagli strumenti di registrazione); separatamente, la modalitàrender.capturedi uno strumento di registrazione pilotahost.recorder, la cui ripresa arriva come un Blob finito nel contenitore che il browser ha registrato. (Gli strumenti che impostanorender.export: false- ad esempio Color Palette, Countdown Timer, Strip Hidden Data, Text, Compress PDF - nascondono i controlli di download/formato/dimensione.) Le unità fisiche vengono convertite per formato in questo punto (PDF → punti pagina reali, raster → pixel al DPI con un chunkpHYs). I metadati di autorialità/provenienza (autore, strumento, fonte - costruiti daengine/src/metadata.ts) vengono incorporati per formato: PNG iTXt, JPEG EXIF, dizionario informazioni PDF,<metadata>SVG, commento GIF. Gli strumenti sperimentali ricevono una filigrana inserita dall'host, non dallo strumento.
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBVerifica tu stessoScarica il file firmato
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBVerifica tu stessoScarica il file firmato
Stesso ciclo di vita in Tauri. Stesso ciclo di vita in CLI - jsdom fornisce il DOM headless; l'output va su file o su stdout.
Stato open source
Il codice è MPL-2.0. engine/, shells/, services/, schemas/ e docs/*.ts sono open source sotto MPL-2.0 - una piattaforma di scaffolding neutrale rispetto al vendor per gli strumenti di brand, tutta in un unico repository pubblico, lolly-tools/lolly.
Il contenuto degli strumenti viene distribuito come brand pack, ciascuno con i propri termini (vedi il NOTICE.md del pacchetto). community/ è una directory di questo repository e i suoi strumenti brand-agnostici sono anch'essi MPL-2.0. brands/suse/ è il pacchetto privato suse-lolly, l'unico submodule: gli strumenti SUSE e il catalogo SUSE, di proprietà esclusiva di SUSE, inclusa la sua musica PremiumBeat su licenza. brands/lolly-start/ è il brand di partenza vuoto di proprietà di questo repository. I font vengono distribuiti all'interno di un pacchetto sotto la SIL Open Font License 1.1 - il pacchetto SUSE include i caratteri SUSE e SUSE Mono.
Non esiste una directory tools/ o catalog/ alla radice del repository. packages/node-shell/src/content-roots.ts risponde a "dove si trova lo strumento <id>" e "dove si trova il catalogo" leggendo profiles.json al momento della lettura, quindi un profilo è una risposta per processo e non è necessario assemblare prima alcun albero. Una vera coppia tools/ + catalog/ viene scritta solo in un output di build - dist/, un payload RPM, un'immagine container - perché un browser recupera quei due percorsi via HTTP.
La separazione è applicata - non ci sono importazioni incrociate da engine/ verso il contenuto degli strumenti - così il confine tra piattaforma e contenuto resta pulito.
Dove finisce il motore e inizia l'host
Se puoi descriverlo in puri dati + Handlebars → engine. Se tocca il DOM, il filesystem, la rete o una qualsiasi API browser/OS → host.
La linea è netta di proposito. Il motore è la parte open source. Tutto ciò che conosce SUSE, piattaforme specifiche o ambienti di runtime resta fuori.
Per il livello di dettaglio successivo, engine/README.md elenca ogni modulo del motore e di cosa è responsabile, e Threat Model & Trust Boundaries registra dove quella stessa linea funge anche da confine di fiducia.