Lolly
Otwórz aplikację

Przegląd

signed by Lollyoverview.htmlHTMLpixels, not shapes12 KBAI generatedgenerated by ClaudeSprawdź samodzielniePobierz podpisany plik

Ikona Lolly - duży zielono-biały lizak

Ten dokument opisuje cel, strukturę i decyzje architektoniczne platformy Lolly. Odzwierciedla zarówno wizję produktu, jak i obecny stan kodu.

Status: Lolly zostało wydane. Wersja 1.0 ukazała się jako open source na licencji MPL-2.0 30 sierpnia 2026, a funkcje, ustawienia domyślne i katalog narzędzi nadal zmieniają się między wydaniami. Silnik jest deterministyczny, z jedną ścieżką renderowania za każdą powłoką. Jego bezpieczeństwo nie przeszło jeszcze niezależnego audytu, a dowody wdrożenia mają kilka miesięcy. Zobacz Adoption & Governance, by poznać bieżący stan i sposób mierzenia wdrożenia.

Jak czytać tę stronę. Zawiera dwa rodzaje materiału, w tej kolejności. Pierwsza połowa to dlaczego to istnieje: problem, pozycjonowanie i cykl życia, przez który przechodzi pojedynczy zasób. Od Ogólny obraz w dół to już jak dopasowane są warstwy: dokument architektury dla współtwórców, obejmujący podział na silnik/powłokę/pakiet, układ repozytorium, cele dostarczania i zobowiązania, które ograniczają każdą zmianę w platformie. Jeśli jesteś tu, by zmieniać kod, a nie zrozumieć produkt, zacznij od ogólnego obrazu.

Dwa uzupełniające dokumenty sięgają głębiej niż ta strona. engine/README.md w repozytorium to mapa silnika moduł po module, z wygenerowaną tabelą każdego modułu i tego, co parsuje lub zapisuje. Threat Model & Trust Boundaries to ta sama architektura odczytana jako granice zaufania i to właściwa strona na każde pytanie o to, co silnik traktuje jako niezaufane.


Dlaczego to istnieje

Powtarzalna praca kreatywna jest zbyt przewidywalna, by za każdym razem angażować wykwalifikowane ręce, i zbyt wrażliwa na jakość, by oddać ją bez zabezpieczeń. Pozostawiona samej sobie, przybiera jedną z trzech postaci: staje się powolna, niespójna lub zamknięta w szablonach dostawcy.

Ta platforma jest bezpośrednią odpowiedzią:

Programistyczna kreacja i treści na skalę - zasoby generowane z danych wejściowych, z regułami ustalonymi raz, dla każdego, kto ich potrzebuje.

Lolly to nie miejsce, w którym powstaje system projektowy - to miejsce, w którym jest on produkowany. Pomyśl o tym jak o automacie do projektowania: dokonujesz wyboru, dostajesz wynik. Za każdym razem. Silnik dąży do najwyższej jakości, jaką dany format może uzyskać na sprzęcie, który masz przed sobą, a ten sam silnik tworzy ten sam plik na każdej platformie, na jaką trafia.

Efektem jest obfitość: każde wydarzenie ma poprawne oznakowanie, każdy alert CVE pasuje do stylu firmowego, każda etykieta drukuje się czysto, każda stopka e-mail jest aktualna - wszystko dzięki narzędziom, które już niosą w sobie te reguły. Platforma obsługuje powtarzalną, zoperacjonalizowaną kreację. Celowo nie jest to narzędzie do twórczości na zamówienie - projektanci nadal odpowiadają za flagowe prace.

Innowacja probabilistyczna, skalowanie deterministyczne

Każda dyskusja o AI w procesie kreatywnym utyka na tym samym pytaniu: która część jest zadaniem maszyny? To stare pytanie z ustaloną odpowiedzią. Skrybowie i iluminatorzy pracowali już między dwoma narzędziami - luźnym szkicem, gdzie nic nie było ustalone i wszystko można było wypróbować, oraz prasą drukarską, onieśmielającą właśnie dlatego, że się zobowiązywała. Szkice były miejscem, gdzie działa się sztuka. Prasa była sposobem, by dotarła do kogokolwiek. Nikt nie mylił tych dwóch rzeczy, a obie wciąż się rozwijały - nowe atramenty, nowe kroje, nowe prasy - każda ulepszana w harmonii z rzemiosłem i intencją, której służyła.

Lolly wyznacza tę samą granicę. Eksploruj probabilistycznie: model, projektant, luźny pomysł, prompt, który prowadzi tam, gdzie nikt nie planował. Potem skaluj deterministycznie - rzeczą, która staje się wieloma wynikami, jest narzędzie, a narzędzie renderuje się za każdym razem tak samo, na podstawie danych wejściowych, które można odczytać. Eksploracja pozostaje swobodna, bo nic dalej w łańcuchu nie zależy od tego, czy wypadnie tak samo dwa razy. Wynik zdobywa zaufanie, bo nie jest zgadywanką. Przełożenie eksperymentów z AI na przewidywalne, powtarzalne rezultaty nie jest nową dyscypliną; to ten sam podział pracy, który sprawił, że druk w ogóle zasługiwał na zaufanie.

Ufaj procesowi twórczemu, skaluj z rygorem.

Na tle alternatyw

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

Kompletność możliwości w dzisiejszych narzędziach kreatywnych, na podstawie badania z sierpnia 2026. Punktacja: 0 brak, 25 na poziomie obejścia, 50 realne, ale ograniczone lub częściowe, 75 mocne z zastrzeżeniami, 100 kluczowa kompetencja.

signed by Lollypositioning-comparison.htmlHTMLpixels, not shapes40 KBAI generatedgenerated by GPT-6Sprawdź samodzielniePobierz podpisany plik

Luka jest jasna: nic, co dziś jest dostępne, nie daje nam wyniku opartego najpierw na ograniczeniach, działającego offline, o niskim progu umiejętności i dostępnego wewnętrznie. Lolly zawiera nawet otwarte płótno - Design - gdzie kolory, typografia i zasoby podlegają globalnym ustawieniom marki, więc swobodny układ pozostaje oparty najpierw na ograniczeniach. Czym nie jest, to nieograniczony pakiet projektowy: projektanci nadal używają Illustratora i Figmy do flagowych prac na zamówienie. Permutacje można składać za pomocą tego narzędzia.

Każde narzędzie w bibliotece jako karta, pogrupowane według kategorii, tak by producent mógł jedno wybrać i zacząć signed by Lollyvector SVG367 paths~62k nodes773 groups3 images1453 KBSprawdź samodzielniePobierz podpisany plikKażde narzędzie w bibliotece jako karta, pogrupowane według kategorii, tak by producent mógł jedno wybrać i zacząć signed by Lollyvector SVG367 paths~62k nodes776 groups3 images1454 KBSprawdź samodzielniePobierz podpisany plik

Użyj do: Szybkiego generowania zoperacjonalizowanych zasobów kreatywnych - kafelków wydarzeń, identyfikatorów imiennych, stopek, alertów CVE, kodów QR, kart społecznościowych, etykiet przesyłek, ustrukturyzowanych raportów.

Nie używaj do: Unikalnej twórczości typu hero.


Cykl życia kampanii

Najjaśniejszym sposobem zobaczenia, czym jest Lolly, nie jest lista funkcji - to śledzenie pojedynczego zasobu, gdy przechodzi z rąk do rąk. Prześledź, jak jedna zlokalizowana karta kampanii przemieszcza się przez organizację:

  1. Twórca ustala reguły. Projektant tworzy bazowy szablon w narzędziu Design, na stałe wpisując zmienne typografii i kolorów marki. Nie robi jednej karty - wykonuje pracę podstawową raz, by nigdy więcej nie musieć ręcznie lokalizować.
  2. Deweloper to skaluje. Ten sam szablon jest podłączony do nocnego pipeline'u przez CLI, więc świeży wykres lub nowy wariant językowy generuje się automatycznie - żaden projektant nie otwiera pliku ponownie.
  3. Producent po prostu z tego korzysta. Handlowiec, offline w samolocie, otwiera to samo narzędzie i generuje w pełni zgodną z marką prezentację na spotkanie z klientem. Bez umiejętności projektowych, bez sieci, bez czekania.

"Świeży wykres" z kroku drugiego to render taki jak ten, wygenerowany z ciągu danych i garści parametrów, bez otwierania przez nikogo pliku projektowego:

Wykres warstwowy skumulowany z tytułem, którego trzy serie są ułożone w chłodnej palecie, z osiami, legendą i tytułem rozmieszczonymi przez szablon, a nie ręcznie signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBSprawdź samodzielniePobierz podpisany plikWykres warstwowy skumulowany z tytułem, którego trzy serie są ułożone w chłodnej palecie, z osiami, legendą i tytułem rozmieszczonymi przez szablon, a nie ręcznie signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBSprawdź samodzielniePobierz podpisany plik

Chodzi nie o to, że Lolly jest dobre dla projektantów i dobre dla deweloperów i dobre dla sprzedaży, każde z osobna. To sztafeta: początkową pracę twórcy skaluje deweloper, co z kolei daje siłę producentowi. Bezwysiłkowe doświadczenie nietechnicznego handlowca w samolocie jest możliwe wyłącznie dzięki rygorowi, który ustalił projektant, a wdrożył deweloper.

To jest mnożnik siły. Lolly nie jest szufladą osobnych narzędzi dla osobnych ról - to jeden deterministyczny cykl życia zasobu, którego dotyka każda rola, a każda para rąk, przez którą przechodzi, mnoży wartość poprzedniej.


Jedno narzędzie, wiele wyników

Reguły marki znajdują się w narzędziu, a nie w każdym pliku, który ono tworzy (zobacz Jak Lolly wypada na tle innych). Ustaw narzędzie poprawnie raz, a każdy wynik dziedziczy ten sam krój, kolor i odstępy, niezależnie od tego, czy to jedna karta, czy arkusz kalkulacyjny z wierszami w kilkunastu językach. To, jak sprawdzasz swoją pracę i kto to robi, pozostaje twoją sprawą; Lolly sprawia, że rzecz warta sprawdzenia jest mniejsza, a wynik szybszy do wykonania.

To samo deterministyczne narzędzie osiąga tę skalę na trzy sposoby, z których każdy daje identyczny wynik:

Tryb wsadowy przy świeżej instalacji: jeden pusty wiersz czekający na narzędzie, z całą powierzchnią arkusza i przyciskiem Render już na miejscu, zanim pojawią się jakiekolwiek dane signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBSprawdź samodzielniePobierz podpisany plikTryb wsadowy przy świeżej instalacji: jeden pusty wiersz czekający na narzędzie, z całą powierzchnią arkusza i przyciskiem Render już na miejscu, zanim pojawią się jakiekolwiek dane signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBSprawdź samodzielniePobierz podpisany plik

Jeden zestaw ograniczeń marki, ustalony raz przez projektanta; trzy drogi do identycznego wyniku.


Ogólny obraz: jak dopasowane są warstwy

Wszystko od tego miejsca w dół to architektura. Diagram pokazuje cały system w jednym widoku: narzędzia to dane na górze, silnik pośrodku nie wie nic o żadnej platformie, powłoki poniżej niego implementują jeden kontrakt, a katalogi dostarczają treść.

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

Układ repozytorium

Lolly to jedno repozytorium. engine/, schemas/, scripts/, tests/, api/, docs/, community/, brands/lolly-start/, każdy shells/ oraz oba services/ to zwykłe katalogi w tym repozytorium. Jedynym wyjątkiem jest brands/suse, prywatny submoduł git zawierający pakiet narzędzi SUSE i katalog SUSE, opcjonalny i nieobecny w publicznym klonie. To, które pakiety odczytuje dana kompilacja, określa profil treści (profiles.json), rozwiązywany dla każdego procesu, a nie przełączany globalnie. Zobacz Build Guide » Getting the source, aby poznać polecenie klonowania i sposób zatwierdzania zmian wewnątrz prywatnego pakietu.

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

Model dostarczania platformy

Platforma działa na kilku powierzchniach - web PWA, Tauri desktop/mobile, skryptowalne CLI oraz interaktywne TUI. Wszystkie z nich używają tego samego silnika i tych samych plików narzędzi.

Web (PWA) - główna dystrybucja

Hostowane pod adresem URL kontrolowanym przez SUSE. Działa offline, gdy tylko service worker zapisze w pamięci podręcznej narzędzia i zasoby. To tu większość pracowników, dostawców i partnerów będzie korzystać z platformy. Konto nie jest wymagane - stan jest przechowywany w IndexedDB na każdym urządzeniu.

Powłoka web jest responsywna z jednego układu. Na desktopie narzędzie to zmieniany rozmiarowo pasek boczny z elementami sterującymi obok sceny podglądu z nawigacją po płótnie natywną dla gładzika (Cmd/Ctrl-kółko lub uszczypnięcie, by powiększyć wokół kursora, Space- lub przeciąganie środkowym przyciskiem, by przesuwać, klawisze 0/1/+/− oraz HUD Fit/%). Na urządzeniach mobilnych (≤640px) elementy sterujące zmieniają się w zakotwiczony u góry arkusz z uchwytem do przeciągania, który zatrzaskuje się w pozycji peek/half/full (dotknięcie przełącza) nad statycznym podglądem pełnoekranowym, a pływający przycisk Render otwiera elementy sterujące Export w wyskakującym arkuszu od dołu. Dotyk umożliwia uszczypnięcie do powiększenia i przeciąganie na podglądzie. Ścieżka renderowania i elementy sterujące eksportu są identyczne w obu przypadkach - zmienia się tylko układ interfejsu.

Widok podzielony na desktopie - kontrolki generowane z manifestu po lewej, kanwa na żywo po prawej signed by Lollyvector SVG131 paths~6.1k nodes158 groups1 image142 KBSprawdź samodzielniePobierz podpisany plik

To samo narzędzie na szerokości telefonu, bez drugiego układu do utrzymywania: kontrolki stają się arkuszem u góry, podgląd zajmuje cały ekran, a pigułka renderowania unosi się nad nim.

Audiogram na ekranie o szerokości 430 px - arkusz sterowania u góry, gotowa kwadratowa grafika poniżej oraz pływająca pigułka renderowania signed by Lollyvector SVG97 paths~3.3k nodes113 groups99 KBSprawdź samodzielniePobierz podpisany plikAudiogram na ekranie o szerokości 430 px - arkusz sterowania u góry, gotowa kwadratowa grafika poniżej oraz pływająca pigułka renderowania signed by Lollyvector SVG97 paths~3.3k nodes113 groups100 KBSprawdź samodzielniePobierz podpisany plik

Tryb wsadowy (/pro). Powłoka webowa udostępnia też siatkę wsadową w stylu arkusza kalkulacyjnego (shells/web/src/pro/), która renderuje wiele wierszy naraz w jednym lub wielu narzędziach. Obsługuje odczyt i zapis CSV/TSV oraz wklejanie z arkusza, per-wierszowy szablon/format/rozmiar/jednostkę/dpi, panel boczny edytora bloków z podglądem na żywo, zwijalne kolumny eksportu, pasek tagów "relevance" na wiersz, zmianę kolejności wierszy przez uchwyt przeciągania po lewej, dwuetapowe potwierdzenie usunięcia, zapisane sesje wsadowe i pobieranie w formacie .zip. To jest powierzchnia jeden-do-wielu stojąca za pozycjonowaniem "masowego generowania treści".

Tauri desktop / mobile

Spakowana aplikacja natywna (mały rozmiar dzięki Tauri). Zapewnia pełną dostępność offline, dostęp do systemu plików dla narzędzi zależnych od CLI (PDF Smasher, Font Outliner) i dostęp do kamery. Rozszerzenie narzędzi zaplanowane na połowę 2026.

CLI

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

Użytkownicy desktopu mogą wywoływać wiele narzędzi z terminala. Powłoka CLI ładuje ten sam silnik, tworzy DOM jsdom, uruchamia tę samą ścieżkę renderowania i zapisuje plik. Tryb URL jest transportem - CLI nie jest osobną implementacją. To gwarantuje, że wyniki CLI i GUI są identyczne.

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

Interaktywny odpowiednik CLI: pełnoekranowa aplikacja terminalowa sterowana klawiaturą (zbudowana na Ink) do przeglądania narzędzi, wypełniania danych wejściowych, zapisywania projektów i eksportowania - wszystko bez GUI. Jej most hosta ponownie wykorzystuje implementację CLI dla formatów bez DOM (SVG/EMF/EPS/HTML + tekst/dane) i dodaje stan na dysku pod ~/.lolly oraz opcjonalny podgląd inline. Poza tym ma warstwę renderowania w przeglądarce: ograniczoną bezgłowe Chromium (to samo, które instaluje serwer MCP), które generuje raster/PDF/wideo i przechwytywanie URL na żądanie - napędzając zbudowaną kopię powłoki webowej, więc wynik jest identyczny, i uruchamiając się dopiero przy pierwszym eksporcie takiego formatu. Dzięki temu url-shot (z przycinaniem + zmianą kolorów + wektorowym PDF/SVG) i każde narzędzie raster/pdf działają też w terminalu. Zobacz przewodnik TUI.

Niezależnie od tego, na jakiej powierzchni jesteś, zakładka Capabilities w panelu jest pełną mapą tego, co platforma deklaruje, że potrafi zrobić, pogrupowaną i czytelną bez otwierania choćby jednego narzędzia.


Kategorie narzędzi

Narzędzia są oznaczane category w manifeście do grupowania w galerii.

Wiersze są wymienione w kolejności sekcji galerii. Sekcja utility zawsze renderuje się jako ostatnia w galerii (po każdej innej kategorii, w tym przyszłych) - to szuflada "Offline Utilities" działająca on-device.

KategoriaPrzykładyPlanowane
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 ScreenshotUnit/format converters, more on-device privacy utilities

Te komórki to przykłady, nie inwentarze. To, jakie narzędzia istnieją, jest właściwością zamontowanego profilu, nie tej strony: pakiet marki dodaje własne i może wykluczyć narzędzie społecznościowe, którego wolałby nie dostarczać. catalog/tools/index.json - wygenerowany z manifestów, rejestr faktycznie odczytywany przez galerię - jest listą autorytatywną; aby policzyć, co montuje profil, policz manifesty (ls community//tool.json brands//tools/*/tool.json) zamiast ufać liczbie zapisanej tutaj. (Id narzędzia obecne w dwóch pakietach montuje się raz, z pakietu, który wygrywa.)

Narzędzia są też klasyfikowane według statusu: official (zatwierdzone przez markę, bez znaku wodnego), community (wkład zewnętrzny), experimental (eksporty ze znakiem wodnym). Większość biblioteki to official; nowsze studia i narzędzia przechwytywania mają zwykle status community lub experimental, dopóki się nie ustabilizują. Każda powierzchnia pokazuje odznakę, więc czytelnik wie, co bierze, zanim to otworzy - i, podobnie jak komórki kategorii powyżej, przynależność per-status zmienia się zbyt szybko, by ją tu wyliczać. Odczytaj ją z galerii lub wygenerowanego indeksu.

Design to pierwsze narzędzie zbudowane na wolnej kanwie render.layout: "editor" - bezchromowej powierzchni bezpośredniej manipulacji, na której przeciągasz, zmieniasz rozmiar, obracasz i przyciągasz boksy tekstu, kształtów i obrazów, a następnie eksportujesz tą samą ścieżką renderowania co każde inne narzędzie.

Strip Hidden Data to pierwsze narzędzie działające na urządzeniu (privacy: "on-device"): narzędzie do przekształcania treści, które przyjmuje plik dostarczony przez Ciebie, przetwarza go w całości w przeglądarce i zwraca czystą kopię - nigdy nieprzesyłaną na serwer, nigdy nieznakowaną znakiem wodnym, bez osadzonych metadanych pochodzenia. Text to drugie takie narzędzie - warsztat działający na urządzeniu do codziennych zadań typu wklej-na-stronę (formatowanie JSON, dekodowanie JWT, Base64, kodowanie/dekodowanie URL, haszowanie SHA). Compress PDF to trzecie - zmniejsza plik PDF poprzez ponowną kompresję jego obrazów, również w całości na urządzeniu. Znacznik i tekst jego odznaki "Działa na Twoim urządzeniu - nic nie jest przesyłane" obejmują teraz cały zestaw narzędzi transformujących: Strip Hidden Data, Text, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (niszczenie fragmentów obrazu, SVG lub PDF), Prompt Card i Rebrand (zmiana motywu pliku .pptx w miejscu), tam gdzie profil je montuje. To kategoria narzędzi prywatności, która zastępuje przekazywanie poufnych plików jednofunkcyjnym witrynom.

Szuflada Utilities, gdzie każda karta to narzędzie transformujące plik, który już masz signed by Lollyvector SVG124 paths~29k nodes324 groups395 KBSprawdź samodzielniePobierz podpisany plikSzuflada Utilities, gdzie każda karta to narzędzie transformujące plik, który już masz signed by Lollyvector SVG124 paths~29k nodes324 groups396 KBSprawdź samodzielniePobierz podpisany plik

Uwaga: category i status są zdenormalizowane do catalog/tools/index.json (rejestru odczytywanego przez galerię) na podstawie każdego tool.json. Manifest jest źródłem prawdy - indeks jest generowany przez pnpm run build:catalog, a pnpm run validate:catalog kończy się błędem w CI, jeśli zatwierdzony indeks odbiega od manifestów.


Zobowiązania architektoniczne

Te decyzje są ustalone. Zmiana którejkolwiek z nich to poważne przedsięwzięcie - kształtują każdą inną decyzję w bazie kodu.

1. Deklaratywne narzędzia, z imperatywnym wyjściem awaryjnym

Narzędzie to manifest (tool.json) + szablon (template.html) + opcjonalne hooks.js.

Manifest deklaruje dane wejściowe. Nie szablon. Dane wejściowe nie są wywnioskowane z tokenów Handlebars. Manifest jest umową; szablon konsumuje nazwane zmienne przez {{id}}.

Stos kontrolek Street Map - rozwijana lista miast, wybór motywu, suwaki grubości i wyzwalacze kolorów, każdy z nich narysowany z linii manifestu signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBSprawdź samodzielniePobierz podpisany plikStos kontrolek Street Map - rozwijana lista miast, wybór motywu, suwaki grubości i wyzwalacze kolorów, każdy z nich narysowany z linii manifestu signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBSprawdź samodzielniePobierz podpisany plik

Hooki są opcjonalne. Większość narzędzi jest czysto deklaratywna - manifest + szablon wystarczą. Narzędzia potrzebujące obliczonych wartości (kodowanie QR, kształtowanie danych wykresu) dostarczają hooks.js eksponujące nazwane funkcje cyklu życia (onInit, onInput, onFrame - hook per-klatkowy kamery na żywo dla narzędzi reagujących na ruch - onLevel, beforeExport, afterExport, exportFile - ścieżka transformacji plik-wejście/plik-wyjście używana przez narzędzia on-device jak Strip Hidden Data - i exportStill, dla narzędzia, które ma własny głęboki raster). Host ładuje hooki przez new Function('host', …) z mostem możliwości wstrzykniętym jako zasięg domknięcia. To jest umowa przenośności, nie piaskownica bezpieczeństwa: hooki wciąż działają w realmie strony i mogą sięgać po window/fetch/document w powłoce przeglądarkowej - host. to wspierana, przenośna powierzchnia, nie wymuszona granica. Wyniki asynchronicznych hooków są ograniczone czasowo (onInit 5s, onInput 2s, beforeExport/afterExport 5s, exportFile/exportStill 10s), a spóźnione wyniki są odrzucane; rozbiegany synchroniczny* hook nie może zostać wywłaszczony. Niezaufany kod hooków stron trzecich nie jest więc bezpieczny do uruchamiania, dopóki nie pojawi się izolacja Worker.

Ma to znaczenie, ponieważ: narzędzia deklaratywne mogą być autorowane przez osoby niebędące programistami. Gdyby każde narzędzie było aplikacją webową, ryzyko "ograniczone umiejętności do tworzenia/utrzymywania szablonów roboczych" stałoby się permanentnym wąskim gardłem.

2. Narzędzia i zasoby to dane, nie spakowany kod

Aplikacje web i Tauri pobierają katalogi narzędzi i zasobów ze znanego URL przy starcie, buforują je lokalnie i działają na tym, co tam jest. Dodanie nowego kafelka wydarzenia lub sezonowego zasobu nie wymaga wydania aplikacji.

Bajty zasobów są sumowane kontrolnie SHA-256, by zapobiec zatruciu CDN. id + version zasobu napędzają unieważnianie pamięci podręcznej.

3. Most Możliwości to jedyne API, jakie widzą narzędzia

Narzędzia nigdy nie dotykają DOM poza obszarem swojego szablonu, nigdy nie wywołują fetch bezpośrednio, nigdy nie odczytują systemu plików. Wywołują wersjonowane metody host.*. Kanoniczną definicją umowy jest packages/core/src/host-v1.ts - SDK dla autorów narzędzi @lolly-tools/core, dzięki czemu strona trzecia może budować na tym bez zależności od silnika; engine/src/bridge/host-v1.ts jest jego reeksportem typu, a kod silnika/powłok nadal importuje z tej samej ścieżki bez zmian:

API mostuCo robi
host.profileImię, e-mail, zdjęcie, miasto użytkownika itd. Wstępnie wypełnia dane wejściowe przez bindToProfile.
host.assetsZapytania do katalogu, rozwiązywanie zasobów, UI wyboru dostarczane przez hosta.
host.stateZapis / odczyt slotów danych wejściowych. IndexedDB na webie, system plików na Tauri, pamięć na CLI.
host.clipboardZapis tekstu lub obrazu do schowka (z fallbackami platformowymi).
host.exportRasteryzuje lub serializuje cel renderowania. Nakłada znak wodny dla narzędzi eksperymentalnych.
host.netFetch z listy dozwolonych - dostępny tylko jeśli narzędzie zadeklarowało możliwość "network". (Żadne dostarczane narzędzie obecnie tego nie używa.)

Opcjonalne, addytywne powierzchnie pojawiają się tylko wtedy, gdy dostarcza je powłoka. Niektóre są bramkowane możliwościami - eksponowane tylko wtedy, gdy narzędzie zadeklaruje pasującą flagę: host.compose (osadzenie renderu innego narzędzia - compose), host.capture (przechwytywanie strony dla URL Screenshot - capture) i host.recorder (przechwytywanie mikrofonu/kamery/ekranu dla narzędzi nagrywających - microphone / camera / screen). Reszta jest wykrywana funkcjonalnie - obecna zawsze, gdy powłoka może ją dostarczyć, przy czym narzędzie zachowuje fallback dla powłok, które nie mogą.

Garść flagowych powierzchni, by pokazać zakres - Host API dokumentuje każdą z nich, a packages/core/src/host-v1.ts jest samą umową:

InterfejsOd wersjiCo dodaje
host.tokens1.0Tokeny projektowe DTCG - własne prymitywy marki
host.text1.0Zamiana tekstu na ścieżki przez HarfBuzz WASM (flaga możliwości wasm oznacza narzędzia, które z tego korzystają)
host.media1.4Klatki z kamery na żywo napędzające hook onFrame. Stopniowe udoskonalenie, celowo nie uzależnione od flagi camera - takie narzędzie nadal działa jako zwykłe narzędzie do nieruchomych obrazów
host.color1.40Percepcyjna matematyka koloru: ΔEOK, kontrast WCAG + APCA, rampy OKLab, podziały na klasy, palety kategoryczne, schematy harmonii (1.60), mieszanie CSS Color 4 i wypalanie gradientów (1.68). Czyste i synchroniczne - powłoki dołączają makeColorApi() silnika zamiast czegokolwiek implementować, więc nie może dojść do rozjazdu
host.images1.60Dekodowanie / zmiana rozmiaru / ponowne kodowanie bajtów na urządzeniu - ścieżka konwersji (HEIC → JPEG, kompresja do WebP, pomniejszanie). Dostarczane w powłoce webowej jako leniwa fasada, więc dekoder HEIC nigdy nie trafia do fragmentu startowego
host.geom1.64Dokładna geometria wektorowa: operacje logiczne na ścieżkach, offsetowanie, zamiana obrysu na wypełnienie, obniżanie splajnów, uproszczanie, wykrywanie trafień. Także czyste, synchroniczne i dołączane z silnika (makeGeomApi()); błędy są zwracane, nigdy nie rzucane

Reszta stosuje się do tych samych zasad i jest dokumentowana obok nich: pdf (1.8) i pptx (1.58) do chirurgii dokumentów on-device, audio (1.71) i speech (1.96) do analizy klipów i TTS/transkrypcji on-device, viz (1.72) do umowy zastępczej MilkDrop, codec (1.100) i layers (1.102) do wyjścia głębokich bitów i warstwowej mapy bitowej, upscale (1.101) i matte (1.103) do modeli on-device, raster (1.105) dla hooków wykonujących własną pracę na pikselach, connectors (1.106) dla strzałek bezpiecznych przy eksporcie i c2pa (1.85) do podpisywania gotowych bajtów. Liczba rośnie; zasady nie.

Deklarowalne możliwości to: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, dodana w 1.54, to przechwytywanie ekranu przez host.recorder - użytkownik wybiera ekran/okno/kartę w natywnym UI przeglądarki; różni się od capture, które rasteryzuje URL nazwany przez samo narzędzie.)

To samo narzędzie działa w przeglądarce, Tauri i bezgłowym CLI, ponieważ każda powłoka implementuje ten interfejs - narzędzie nigdy nie wie, w której jest.

Most jest wersjonowany. Dodanie metod to wersja pomniejsza. Usunięcie lub zmiana sygnatur to skok wersji głównej. Gdy wyjdzie v2, v1 musi nadal działać.

4. Id zasobów są wieczne

suse/logo/primary to umowa. Po opublikowaniu:

To sprawia, że zapisane stany narzędzi i linki dzielone przez URL są trwałe przez lata.

5. Tryb URL jest pierwszorzędny

Każde dane wejściowe muszą dać się wyrazić jako parametr URL:

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

Ten link sam w sobie, bez niczego więcej, jest gotowym zasobem signed by Lollyvector SVG55 paths~2.6k nodes38 groups60 KBSprawdź samodzielniePobierz podpisany plikTen link sam w sobie, bez niczego więcej, jest gotowym zasobem signed by Lollyvector SVG55 paths~2.6k nodes38 groups61 KBSprawdź samodzielniePobierz podpisany plik

Tryb CLI to tryb URL pod innym transportem - powłoka CLI buduje obiekt stanu URL z argv i uruchamia ten sam potok silnika. Istnieje jedna ścieżka renderowania. CLI nie może dryfować od GUI, bo nie jest osobną implementacją.

url-mode.ts obsługuje przejazd tam i z powrotem (parsowanie i serializację). Zbiór zarezerwowanych parametrów nigdy nie jest przekazywany do narzędzia jako dane wejściowe: kontrolki wyjścia (format, export, copy, filename, width/w, height/h, unit, dpi), pokrętła druku i proweniencji (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) i nośniki stanu (template, z - spakowany token "Shortest link" - oraz zx, ten sam zaszyfrowany hasłem). Zbiór RESERVED w engine/src/url-mode.ts jest autorytetem i jest przypięty testem; Tryb URL dokumentuje każdy z nich, w tym garść niewymienionych tutaj. Dane wejściowe zasobów w trybie URL są serializowane przez ich id; runtime rozwiązuje je przez host.assets.get() przed hydratacją. width/height to wartości w unit (domyślnie px, także mm/cm/in/pt/pc); przy jednostce fizycznej dpi ustawia rozdzielczość rastra. Ustawiają rozmiar dokumentu kanwy i wstępnie wypełniają panel wymiarów eksportu.

Ponieważ każde dane wejściowe podróżują w linku, zmiana parametru to inny gotowy zasób. Cała ta paleta to jeden kolor bazowy, harmonia i liczba kroków:

Dziewięć kroków w czterech odcieniach, wszystkie wyrosłe z pojedynczego koloru bazowego przekazanego w linku signed by Lollyvector SVG10 groups25 KBSprawdź samodzielniePobierz podpisany plikDziewięć kroków w czterech odcieniach, wszystkie wyrosłe z pojedynczego koloru bazowego przekazanego w linku signed by Lollyvector SVG10 groups25 KBSprawdź samodzielniePobierz podpisany plik

6. Przechowywanie danych odbywa się przez mostek, nie bezpośrednio

Web shell: IndexedDB. Tauri: system plików. CLI: pamięć tymczasowa. Narzędzia widzą tylko host.state.save(slot, data) i host.state.load(slot). localStorage nie jest używany - jest zbyt mały i nie może przechowywać blobów.

Użytkownicy mogą zapisać wiele nazwanych slotów edycji dla każdego narzędzia i wrócić do każdej sesji później. Nie jest wymagane zakładanie konta; stan jest przechowywany lokalnie na urządzeniu. Ponieważ mostek jest jedynym punktem styku, ten lokalny stan jest też przenośny: shells/web/src/data-transfer.ts odczytuje wszystko z powrotem przez host.profile/host.state/host.assets do jednego pliku zip lolly-backup, który importuje się na dowolnej innej instalacji - offline'owa odpowiedź na "przeniesienie na nowe urządzenie", niewymagająca serwera (pełna specyfikacja: docs/data-transfer.md). Synchronizacja wielourządzeniowa działa już na tej podstawie, wysyłając tę samą paczkę do pamięci wybranej przez użytkownika (docs/sync.md).

7. Znaczniki dojrzałości mówią, czym jest narzędzie

Każde narzędzie deklaruje status: official | community | experimental w swoim manifeście. Galeria sortuje według statusu. Narzędzia eksperymentalne automatycznie znakują swoje eksporty znakiem wodnym - znak wodny jest nakładany przez host.export.render, a nie przez narzędzie, więc autor narzędzia niebędącego oficjalnym nie może z niego zrezygnować.

To strukturalna odpowiedź na ryzyko odbioru, że każde narzędzie w galerii waży tyle samo. Jakikolwiek proces zespół nałoży na katalog, nakłada się on na to rozwiązanie.

8. Dane wejściowe narzędzia są typowane poprzez manifest, w tym zasoby

Dane wejściowe deklarują type: text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table i file. Host renderuje generyczną kontrolkę dla każdego typu na podstawie manifestu - narzędzia nie piszą ani jednej linii kodu kontrolek. (Wstępne wypełnianie z profilu użytkownika nie jest typem - każde pole wejściowe może mieć bindToProfile.) Trzy z nich mają większe znaczenie niż pozostałe:

9. Szablony są bezlogikowe (Handlebars, nie EJS)

Handlebars został wybrany zamiast EJS celowo:

Logika żyje w hooks.js, gdzie jest jawna i możliwa do zrecenzowania. Dostępne helpery Handlebars: {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (a także helpery formatowania danych icsStamp/rfcText/csvCell używane przez towarzyszące szablony .ics/.vcf/.csv).

10. Narzędzia komponują narzędzia

Narzędzie może osadzić render innego narzędzia bez importów między narzędziami - kompozycja jest rozwiązywana przez silnik, nigdy przez kod narzędzia. Istnieją dwie powierzchnie:

Można komponować render dowolnego narzędzia: dziecko w formacie SVG pozostaje prawdziwym wektorem, gdy rodzic eksportuje do SVG lub PDF, i rasteryzuje się ostro dla PNG; dzieci PNG/JPG/WEBP osadzają się jako obrazy. Wymaga możliwości compose. Skomponowane dzieci są elementami pośrednimi - nigdy nie są znakowane wodnie ani stemplowane pochodzeniem - a kompozycja degraduje się łagodnie: powłoka, która nie potrafi wyrenderować dziecka, po prostu pomija to miejsce, a rodzic i tak się renderuje.


Czego celowo nie zrobiliśmy


Cykl życia jednego renderu

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

  1. Uruchomienie (Boot). Powłoka webowa otwiera IndexedDB, tworzy most możliwości (capability bridge), synchronizuje katalogi narzędzi i zasobów (lub wczytuje je z pamięci podręcznej w trybie offline).
  2. Routing. Hash URL → widok tool, z wyodrębnionymi qr-code i parametrami URL.
  3. Wczytywanie. loadTool('qr-code', fetchFile) pobiera tool.json, waliduje go względem schematu JSON, pobiera template.html, styles.css i kod źródłowy hooks.js.
  4. Parsowanie stanu URL. parseUrlState przekształca parametry URL w początkowe wartości wejściowe. Odniesienia do zasobów (?logo=suse/logo/primary) są parsowane jako lekkie obiekty { id, _unresolved: true }.
  5. Runtime. createRuntime(tool, host, initialValues) buduje model wejść (łącząc dane profilu, wartości domyślne i wartości początkowe), rozwiązuje odniesienia do zasobów przez host.assets.get(), wczytuje hooki (host w zasięgu domknięcia, bez piaskownicy), wywołuje hooks.onInit.
  6. Renderowanie. Powłoka subskrybuje runtime; przy każdej zmianie stanu otrzymuje { model, hydrated }. Renderuje kontrolki wejściowe na podstawie modelu i zapisuje uwodniony HTML szablonu do #tool-canvas.
  7. Interakcja. Użytkownik wpisuje coś w polu wejściowym → runtime.setInput(id, value) → zastosowanie ograniczeń → wywołanie hooks.onInput → ponowne uwodnienie → ponowne renderowanie. Płótno aktualizuje się na żywo.
  8. Eksport. Użytkownik klika Pobierz (PNG) → runtime.export(canvasNode, 'png') → host.export.render (rasteryzacja przez dom-to-image-more; SVG/PDF przechodzą przez dedykowane wektoryzatory przechodzące drzewo DOM) → blob → host.export.download. Zakres formatów, na które może zdecydować się narzędzie, jest szeroki, a wyliczenie render.formats w schemas/tool.schema.json jest tu autorytetem - rastry i rastry zmiennoprzecinkowe, wektory i pliki do wycinania, druk/CMYK, ruch, dokumenty edytowalne (pptx, docx, odt), palety oraz dane/wyjścia tekstowe, pliki audio i czcionek. URL Mode wymienia każdy identyfikator i to, co produkuje. Audio znajduje się w tym wyliczeniu jak wszystko inne (wav, mp3, m4a, opus, deklarowane przez audiogram i narzędzia nagrywające); osobno, tryb render.capture narzędzia nagrywającego steruje host.recorder, którego nagranie trafia jako gotowy Blob w dowolnym kontenerze nagranym przez przeglądarkę. (Narzędzia ustawiające render.export: false - np. Color Palette, Countdown Timer, Strip Hidden Data, Text, Compress PDF - ukrywają kontrolki pobierania, formatu i wymiarów.) Jednostki fizyczne są tu konwertowane osobno dla każdego formatu (PDF → rzeczywiste punkty strony, raster → piksele przy określonym DPI z fragmentem pHYs). Metadane autorstwa/pochodzenia (autor, narzędzie, źródło - budowane przez engine/src/metadata.ts) są osadzane w zależności od formatu: PNG iTXt, JPEG EXIF, słownik informacyjny PDF, <metadata> w SVG, komentarz GIF. Narzędzia eksperymentalne otrzymują znak wodny wstawiany przez hosta, nie przez samo narzędzie.

Panel eksportu otwierany przez ?options: para nazwa pliku i format, rozmiar wyjściowy oraz kontrolki zapisujące plik signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBSprawdź samodzielniePobierz podpisany plikPanel eksportu otwierany przez ?options: para nazwa pliku i format, rozmiar wyjściowy oraz kontrolki zapisujące plik signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBSprawdź samodzielniePobierz podpisany plik

Ten sam cykl życia w Tauri. Ten sam cykl życia w CLI - jsdom dostarcza bezgłowy DOM; wynik trafia do pliku lub na stdout.


Status open source

Kod jest na licencji MPL-2.0. engine/, shells/, services/, schemas/ i docs/*.ts są open source na licencji MPL-2.0 - neutralna wobec dostawców platforma szkieletowa dla narzędzi marki, cała w jednym publicznym repozytorium, lolly-tools/lolly.

Treść narzędzi jest dostarczana jako pakiety marki (brand packs), każdy z własnymi warunkami (zobacz plik NOTICE.md danego pakietu). community/ to katalog tego repozytorium, a jego narzędzia niezależne od marki są również na licencji MPL-2.0. brands/suse/ to prywatny pakiet suse-lolly, jedyny submoduł: narzędzia SUSE i katalog SUSE, własność SUSE, w tym licencjonowana muzyka PremiumBeat. brands/lolly-start/ to pusta marka startowa, której właścicielem jest to repozytorium. Czcionki są dostarczane wewnątrz pakietu na licencji SIL Open Font License 1.1 - pakiet SUSE zawiera kroje pisma SUSE i SUSE Mono.

Nie istnieje katalog tools/ ani catalog/ w katalogu głównym repozytorium. packages/node-shell/src/content-roots.ts odpowiada na pytania „gdzie znajduje się narzędzie <id>” i „gdzie jest katalog” na podstawie profiles.json w momencie odczytu, więc profil jest odpowiedzią ustalaną dla danego procesu i nie trzeba wcześniej budować żadnego drzewa katalogów. Prawdziwa para tools/ + catalog/ jest zapisywana wyłącznie w wyniku builda - dist/, ładunku RPM, obrazie kontenera - ponieważ przeglądarka pobiera te dwie ścieżki przez HTTP.

Podział jest egzekwowany - nie ma importów krzyżowych z engine/ do treści narzędzi - dzięki czemu granica między platformą a treścią pozostaje czysta.


Gdzie kończy się silnik, a zaczyna host

Jeśli da się to opisać w czystych danych + Handlebars → silnik. Jeśli dotyka DOM, systemu plików, sieci lub dowolnego API przeglądarki/systemu operacyjnego → host.

Ta granica jest celowo ostra. Silnik to część open source. Wszystko, co wie o SUSE, konkretnych platformach czy środowiskach uruchomieniowych, pozostaje poza nim.

Kolejny poziom szczegółów: engine/README.md wymienia każdy moduł silnika i za co odpowiada, a Model zagrożeń i granice zaufania opisuje, gdzie ta sama granica jest jednocześnie granicą zaufania.