Този документ описва предназначението, структурата и архитектурните решения за платформата Lolly. Той отразява както визията за продукта, така и текущото състояние на кодовата база.
Статус: Lolly е вътрешен прототип в затворен пилот, който все още не е завършен. Двигателят е детерминиран и вътрешно съгласуван, но продуктът е в ранен етап - SUSE е клиент номер едно - и неговите криптографски и файлово-парсиращи двигатели в момента преминават през строгото инфраструктурно закаляване на SUSE, подготвяйки се за корпоративен мащаб (в това сме наистина добри). Чети архитектурата по-долу като проектно намерение в процес на тестване, а не като завършен, сертифициран продукт. Виж Приемане и управление за това как се провежда и измерва пилотът.
Как да четеш тази страница. Тя съдържа два вида материал, по ред. Първата половина е защо това съществува: проблемът, позиционирането и жизненият цикъл, през който преминава един актив. От Голямата картина нататък е как пасват слоевете: архитектурният документ за контрибутори, обхващащ разделянето engine/shell/pack, оформлението на хранилището, целите за доставка и ангажиментите, които ограничават всяка промяна в платформата. Ако си тук, за да промениш кодовата база, а не за да разбереш продукта, започни от голямата картина.
Два придружаващи документа навлизат по-надълбоко от тази страница.
engine/README.mdв хранилището е картата на двигателя модул по модул, с генерирана таблица за всеки модул и какво парсва или записва той. Модел на заплахите и граници на доверие е същата архитектура, прочетена като граници на доверие, и е правилната страница за всеки въпрос за това какво двигателят третира като недоверено.
Защо това съществува
Екипите се сблъскват с повтарящ се проблем: повтаряща се творческа и съдържателна работа, която е прекалено предвидима, за да оправдава ангажирането на опитни ръце всеки път, но прекалено чувствителна към качество, за да бъде прехвърлена без предпазни огради. Резултатът е или бавна пропускателна способност (тясно място около специалиста), или непоследователност (хора, които използват какъвто инструмент имат под ръка), или обвързаност с доставчик (SaaS DAM, който контролира шаблоните ти).
Тази платформа е прекият отговор на това:
Програмно творчество и съдържание в мащаб - генериране на активи без ръчен труд, с правила под централен контрол, за служители, доставчици и партньори.
Lolly не е мястото, където се изобретява дизайн система - той е мястото, където тя се произвежда. Мисли за него като за автомат за дизайн: правиш избор, получаваш резултат. Всеки път. Енджинът се стреми към най-високото качество, което всеки формат може да произведе на хардуера пред теб, и същият енджин прави същия файл на всяка платформа, на която се доставя.
Резултатът е изобилие: всяко събитие има правилни табели, всяко CVE предупреждение съответства на фирмения стил, всеки етикет се отпечатва чисто, всеки имейл подпис е актуален - всичко това без дизайнерска заявка. Платформата обработва повтарящото се, операционализирано творчество. Тя умишлено не е инструмент за индивидуален творчески дизайн - дизайнерите продължават да притежават флагманската работа.
Иновирай вероятностно, мащабирай детерминирано
Всеки спор за изкуствения интелект в творческия процес се заковава на един и същ въпрос: коя част от това е работа на машината? Това е стар въпрос с установен отговор. Писарите и илюминаторите отдавна са работили с два инструмента - свободната скица, където нищо не е фиксирано и всичко може да се пробва, и печатната преса, плашеща именно защото се обвързва. Скиците бяха мястото, където се раждаше изкуството. Пресата беше начинът, по който то достигаше до всеки. Никой не бъркаше двете, и двете продължаваха да напредват - нови мастила, нови шрифтове, нови преси - всяко подобрение вървеше в хармония с занаята и намерението, на което служеше.
Lolly прокарва същата линия. Изследвай вероятностно: модел, дизайнер, груба идея, промпт, който отива някъде, което никой не е планирал. После мащабирай детерминирано - това, което достига десет хиляди изхода, е инструмент, а инструментът се рендира по един и същ начин всеки път от входове, които можеш да прочетеш. Изследването остава свободно, защото нищо надолу по веригата не зависи от това дали ще се получи еднакво два пъти. Резултатът печели доверие, защото не е предположение. Превръщането на експериментирането с изкуствен интелект в предвидими, възпроизводими резултати не е нова дисциплина; това е същото разделение на труда, което направи печатната работа достойна за доверие още от самото начало.
Довери се на творческия процес, мащабирай с точност.
Спрямо алтернативите
| Capability | Lollyconstraint-first | Penpotopen design | CanvaAffinity Cavalry |
Adobedesktop pro | Brand DAMFrontify Bynder |
Cloudinarymedia pipeline | Figmaonline pro | Render APIsBannerbear Placid Creatomate |
|---|---|---|---|---|---|---|---|---|
| Overall completenessunweighted mean - weight rows for your own context · columns are sorted by this row | 84 | 70 | 57 | 48 | 41 | 41 | 41 | 34 |
Production maturity & track recordCanva, Adobe, Figma, Bynder/Frontify: a decade-plus at massive scale. Render APIs: years in production pipelines. Penpot: shipping, large community, younger at enterprise scale. Lolly: closed pilot, security hardening underway, no public case studies. Cloudinary: 2012, enterprise media infrastructure at global scale. |
25 | 75 | 100 | 100 | 100 | 100 | 100 | 75 |
Mass generation from data (CSV / API)Lolly: batch grid + CLI, one file per row. Canva: Bulk Create + Autofill API - real, but Enterprise-gated, async, text/image fields only; Affinity Publisher adds desktop data merge. Adobe: InDesign data merge and scripting. Figma: Buzz fills templates from CSV or XLSX, free in beta (Aug 2026) - cloud- and account-gated, 50. Penpot: open API/MCP, not purpose-built. Render APIs: this is their entire product - account- and cloud-gated, so 75 under the method rule. DAM: Studio-style batch create and resize. Cloudinary: URL-driven overlays and named transforms derive variants at scale - account-gated, 75. |
100 | 50 | 50 | 50 | 75 | 75 | 50 | 75 |
Offline & air-gap operationLolly: static deploy, no server in the render path, MDM/air-gap. The Canva column is scored on its best family member: Affinity (free since Oct 2025) runs offline as a desktop suite once a verified account activates it - 75, the same deduction Adobe takes. Canva's own Offline (2026) still edits pre-synced designs only, per device, in a 14-day window. Adobe: desktop apps run offline; licensing phones home. Figma: cached-file viewing and limited editing. Penpot: self-host on your infra behind a firewall (server required). Cloud APIs and DAM: none. |
100 | 75 | 75 | 75 | 0 | 0 | 25 | 0 |
On-device rendering - data never leavesLolly: renders and converts in-browser or CLI, locally; zero upload. Adobe: local desktop rendering, but cloud services and telemetry in the suite. Figma: canvas renders locally, files live in Figma's cloud. Penpot: 90 - rendering happens in the browser and the save target is a server that can be your own sovereign private cloud, even your own laptop, with private export throughout; only the server hop separates it from Lolly. Canva itself is server-side by design; the column's 75 is Affinity - local desktop rendering, account activation and telemetry, the same shape as Adobe. Render APIs, DAM: server-side by design. |
100 | 90 | 75 | 75 | 0 | 0 | 25 | 0 |
Hard brand constraints (structural)Lolly: rules compiled into template code - off-brand output is impossible, not just discouraged. Canva: element locks - permission-based, admin-set and static: no template logic such as conditional logo switching or responsive recomposition at fill time, and Canva AI does not yet respect Brand Controls - 50. Render APIs: templates are fixed (only declared fields vary) but no governance layer. DAM: locked templates with restrictions. Figma: Buzz templates hold locked guidelines at fill time; the design surface stays review-enforced - 50. Penpot: tokens and systems enforced by review, not runtime. Adobe: libraries, little enforcement. Cloudinary: presets and Enterprise-gated transformation templates fix operations, not brand layout - 50. |
100 | 50 | 50 | 25 | 75 | 50 | 50 | 75 |
C2PA provenance, signed at creationAdobe: the broadest shipped implementation (Photoshop, Lightroom, Premiere, Firefly) - signing happens locally in the desktop apps and in the cloud for the Content Authenticity web app, and nothing signs without an Adobe account and an Adobe-provisioned identity, so it is account-gated end to end: 75 under the method rule. Lolly: on-device key generation, offline signing, plus pixel imprint - no account anywhere; the on-device key reads as unverified in stock validators (the interim trust list froze Jan 2026) until an identity or an organization's own CA vouches for it, and the stack is pilot-stage and unaudited, so 75. Penpot: 50 via the official Lolly Export plugin - the same on-device engine signing Lolly uses, opt-in rather than default (and disclosed plainly: it is Lolly's own plugin). No evidence of C2PA writing in Canva, Figma, render APIs or DAM as of Aug 2026. Cloudinary: 50 - signs images on delivery (fl_c2pa, CAI member since 2020), attesting delivery by Cloudinary rather than creation by you. |
75 | 50 | 0 | 75 | 0 | 50 | 0 | 0 |
CLI, pipeline & AI-agent automationLolly: CLI, TUI, MCP server, URL mode - one engine everywhere. Render APIs: API-first, webhooks, integrations - account- and cloud-gated, so 75 under the method rule. Penpot: open API, plugins, official MCP server. Canva: Connect API - Enterprise-gated, async, rate-limited. Adobe: UXP/ExtendScript plus Firefly APIs. Figma: strong REST/plugin API, no render pipeline. DAM: asset-management APIs. Cloudinary: API-first media pipeline - account-gated, 75. |
100 | 75 | 50 | 50 | 50 | 75 | 50 | 75 |
Live collaboration (real-time co-editing)The capability that trades most directly against offline. Figma: the scale benchmark - 200 simultaneous editors, up to 500 people in a file - account and cloud required. Canva: mature real-time editing across the product, same precondition. Penpot: real-time multiplayer with live cursors; self-hosting lifts the vendor-account precondition, but a server is still required. Lolly: pairwise P2P shipped - an invite/accept ceremony (QR, link or code), LAN-first, zero server, no account, works fully air-gapped - no large rooms, so Partial; the only column that collaborates with no internet at all. Adobe: Live Co-Editing in beta, cloud documents only. Render APIs: no editing surface. DAM: comments and approvals, not canvas co-editing. Cloudinary: DAM comments and workflows, no canvas co-editing. |
50 | 75 | 75 | 25 | 25 | 25 | 75 | 0 |
No design skill requiredCanva: the category benchmark for ease. DAM: fill a locked template. Lolly: fill in fields - but someone technical must author tools first (the cold-start cost sits with builders, not producers). Render APIs: swaps design skill for developer skill. Adobe, Figma, Penpot: professional tools. Cloudinary: the media library is easy; transformations are developer territory. |
100 | 25 | 100 | 25 | 100 | 50 | 25 | 50 |
Open source, self-hosted, no lock-inPenpot: MPL-licensed, 51k+ stars, self-host via Docker/K8s - fully verifiable today. Lolly: MPL-2.0, the repository is public (github.com/lolly-tools/lolly), OBS builds, no contributor agreement - and it is young: months in public, no external audit, a community still forming, with SUSE maintaining it as a user of its own systems. 75 while youth is the honest deduction. Everything else is proprietary SaaS or proprietary desktop. |
75 | 100 | 0 | 0 | 0 | 0 | 0 | 0 |
Cost at production scaleLolly and Penpot: zero marginal cost on your own hardware. Render APIs: metered - roughly $0.005–0.049 per image, credits often expiring monthly. Canva/Figma: per-seat; Canva's automation needs Enterprise, though Affinity itself is free since Oct 2025. Adobe: premium per-seat suite. DAM: sales-led enterprise quotes, MAU or seat models. Cloudinary: credit-metered across transforms, storage and bandwidth - 25. |
100 | 100 | 50 | 25 | 25 | 25 | 50 | 25 |
Annual medium enterprise spendIndicative list-price arithmetic for a medium enterprise - think 500-5000 people - August 2026: a guess range, not a quote; deals vary and the seat mix dominates. Ring = how much of the board's largest annual spend (US$500k) you keep; the number in the ring is each range's upper bound. Canva (US$75k-400k; Affinity free since Oct 2025 pulls the design-seat share down), Adobe (US$100k-500k) and Figma (US$30k-250k) assume the realistic creative-seat share of an organisation this size - tens to hundreds of seats, not a licence for every employee. Render APIs price by usage (US$5k-60k). DAM is quote-only, commonly US$50k-250k and up. Penpot is hand-set at 99: "your server" can be your own laptop - a small technical hurdle at well under 1% of an Adobe-scale spend. Lolly: US$0 by licence - the apps ship free, run offline and keep working in perpetuity; works on devices immediately, config optional; hosting an instance is an organisation's choice, not a cost of entry. Cloudinary: US$30k-150k, credit-based; enterprise contracts commonly sit near US$82k. |
$0 | $0 | $400k | $500k | $250k+ | $150k | $250k | $60k |
Пълнота на възможностите в днешните творчески инструменти, проучени през август 2026. Скала: 0 липсва, 25 на ниво заобиколно решение, 50 реално, но ограничено или частично, 75 силно с уговорки, 100 основна компетентност.
signed by Lollypositioning-comparison.htmlHTMLAI generatedgenerated by ClaudeПровери самGet the signed filepixels, not shapes38 KBРазликата е ясна: нищо, което се предлага днес, не ни дава изход, ориентиран първо към ограниченията, способен да работи офлайн, с ниски изисквания за умения и вътрешно достъпен. Lolly дори включва отворено платно - Design - където цветовете, шрифтовете и активите се съобразяват с глобалните настройки на марката, така че свободното подреждане остава ориентирано първо към ограниченията. Това, което не е, е неограничен дизайнерски пакет: дизайнерите продължават да използват Illustrator и Figma за индивидуална флагманска работа. Пермутации могат да бъдат съставени с този инструмент.
signed by Lollyvector SVGПровери самGet the signed file281 paths~38k nodes443 groups6 images2269 KB
signed by Lollyvector SVGПровери самGet the signed file281 paths~38k nodes443 groups6 images2270 KB
Използвай го за: Бързо генериране на операционализирани творчески активи - плочки за събития, баджове с имена, подписи, CVE предупреждения, QR кодове, социални карти, етикети за пратки, структурирани отчети.
Не го използвай за: Индивидуално флагманско съдържание.
Жизненият цикъл на една кампания
Най-ясният начин да видиш какво е Lolly не е списък с функции - а да проследиш един-единствен актив, докато минава от ръка на ръка. Наблюдавай как една локализирана карта за кампания преминава през организацията:
- Творецът задава правилата. Дизайнер създава базовия шаблон в инструмента Design, вграждайки типографията и цветовите променливи на марката. Той не прави една карта - върши основната работа веднъж, за да не му се налага никога повече да я локализира ръчно.
- Разработчикът я мащабира. Същият шаблон е включен в нощен процес чрез CLI, така че нова диаграма или нов езиков вариант се генерира автоматично - никой дизайнер не отваря отново файла.
- Продуцентът просто го използва. Търговски представител, офлайн в самолет, отваря същия инструмент и генерира перфектно съобразена с марката презентация за среща с клиент. Без дизайнерски умения, без мрежа, без чакане.
„Новата диаграма" в стъпка две е рендиране като това тук, произведено от низ с данни и шепа параметри, без никой да отваря дизайнерски файл:
signed by Lollyvector SVGПровери самGet the signed file15 paths~1.3k nodes4 groups21 KB
signed by Lollyvector SVGПровери самGet the signed file15 paths~1.3k nodes4 groups21 KB
Смисълът не е, че Lolly е добър за дизайнери и добър за разработчици и добър за продажби, всеки във вакуум. Това е щафета: първоначалната работа на твореца се мащабира от разработчика, което на свой ред дава сила на продуцента. Безусилното изживяване за нетехническия представител в самолета е възможно само благодарение на точността, зададена от дизайнера и внедрена от разработчика.
Това е умножителят на сила. Lolly не е чекмедже с отделни инструменти за отделни роли - това е един детерминиран жизнен цикъл на активи, до който се докосва всяка роля, и всяка ръка, през която преминава, умножава стойността на предишната.
Едно одобрение, десет хиляди активи
Тъй като одобрението живее в инструмента, а не във файла (виж Как се сравнява Lolly), мащабът престава да е проблем на прегледа. Одобри инструмент за локализирана социална карта веднъж и после генерирай 10 000 активa на 12 езика от таблица - и нито един от тях не се нуждае от нова проверка за съответствие от правния отдел или марката, защото шаблонът, от който идват всички, вече е одобрен.
Един и същ детерминиран инструмент достига този мащаб по три начина, всички произвеждащи идентичен, предварително одобрен резултат:
- Човек, в приложението. Партидната мрежа
/pro: постави или импортирай редовете, получи по един готов актив на ред, изтегли zip файла. Без дизайнерски умения, без заявка, без чакане. - Разработчик, от командния ред. CLI пуска същия двигател и същия път на рендиране без графичен интерфейс, така че инструментът може да бъде последователно приложен върху всички 10 000 реда в скрипт или нощен процес. Извикване
lolly <tool> --field=…в цикъл е цялата интеграция. - Система или AI агент, чрез MCP. Същият инструмент, управляван програмно, със същата точност и дори по-голям мащаб - защото машината не се уморява, докато хиляди файлове се обработват.
signed by Lollyvector SVGПровери самGet the signed file348 paths~77k nodes537 groups7 images3100 KB
signed by Lollyvector SVGПровери самGet the signed file348 paths~77k nodes544 groups7 images3103 KB
Един набор от ограничения на марката, зададен веднъж от дизайнер; три пътя до идентичния предварително одобрен резултат - и машинният път се мащабира най-далеч от всички, защото никога не се уморява, докато файловете се обработват.
Голямата картина: как пасват слоевете
Всичко оттук нататък е архитектура. Диаграмата е цялата система в един изглед: инструментите са данни най-отгоре, двигателят по средата не знае нищо за никоя платформа, обвивките под него имплементират един договор, а каталозите доставят съдържанието.
┌─────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────┘
Оформление на хранилището
Съдържанието е монтирано като пакети: community/, docs/, всеки shells/, двата services/ и brands/suse са всеки свое собствено хранилище, изтеглени като git подмодули на това. Родителят притежава engine/, schemas/, scripts/, tests/, api/, brands/lolly-start/ и profiles.json. Виж Ръководство за build » Получаване на кода за командата за изтегляне и работния процес между хранилищата.
lolly/
├── engine/ # Platform-agnostic core. Open source (MPL-2.0).
│ └── src/
│ ├── index.ts # public surface - loader, runtime, template, inputs, url-mode
│ ├── loader.ts # fetches and validates tool files
│ ├── runtime.ts # orchestrates the 5-step lifecycle
│ ├── template.ts # Handlebars hydration + annotateTemplate
│ ├── inputs.ts # manifest → runtime input model
│ ├── url-mode.ts # URL ↔ input state round-trip
│ ├── validate.ts # JSON Schema validation of manifests
│ ├── compose.ts # resolve nested tool renders (composes)
│ ├── embed.ts # parse portable lolly.tools embed URLs
│ └── bridge/
│ └── host-v1.ts # type re-export of the @lolly-tools/core contract
│
├── shells/
│ ├── web/ # PWA - hosted online; primary distribution
│ │ └── src/
│ │ ├── main.ts # boot, routing
│ │ ├── theme.ts # theme apply/persist (FOUC prevention)
│ │ ├── bridge/ # web implementations of HostV1 APIs
│ │ │ ├── index.ts # compose all bridge pieces
│ │ │ ├── db.ts # IndexedDB setup
│ │ │ ├── state.ts # host.state - saved edits
│ │ │ ├── profile.ts # host.profile - user details
│ │ │ ├── assets.ts # host.assets - catalog + user uploads
│ │ │ ├── clipboard.ts # host.clipboard
│ │ │ ├── export.ts # host.export - rasterise/serialize
│ │ │ ├── net.ts # host.net - allowlisted fetch
│ │ │ └── media.ts # host.media - live camera frames (onFrame)
│ │ ├── catalog/
│ │ │ └── sync.ts # boot-time catalog sync + offline cache
│ │ ├── styles/ # app-wide CSS (app.css, picker.css, tokens.css)
│ │ └── views/
│ │ ├── gallery.ts # tool library listing + saved-state cards
│ │ ├── tool.ts # mounts one tool (inputs + canvas + actions)
│ │ ├── picker.ts # asset picker UI (invoked by host.assets)
│ │ ├── profile.ts # user details editor
│ │ ├── projects.ts # /p - folders of saved sessions (nested; folder/selection export)
│ │ └── free-canvas.ts # free-canvas editor overlay for render.layout:"editor" tools
│ │
│ ├── cli/ # Node.js CLI - same engine, headless jsdom
│ │ ├── bin/lolly.ts
│ │ └── src/
│ │ ├── run.ts # loadTool → createRuntime → export → write file
│ │ └── bridge.ts # CLI implementation of HostV1
│ │
│ ├── tui/ # Interactive terminal shell (Ink) - reuses the CLI bridge
│ │ └── src/
│ │ ├── main.tsx # full-screen app: Gallery / Projects / Profile / ToolView
│ │ └── bridge.ts # CLI bridge + on-disk state under ~/.lolly
│ │
│ ├── tauri-desktop/ # downloadable desktop app
│ └── tauri-mobile/ # iOS/Android app
│
├── tools/ # profile VIEW (gitignored) - data, not code. Merged from packs:
│ # community/ (public, brand-agnostic, MPL) + brands/<active>/tools (brand-owned).
│ # A SELECTION follows - the mounted set depends on the profile.
│ ├── qr-code/
│ ├── quotes/
│ ├── email-signature/
│ ├── snippet/
│ ├── countdown-timer/
│ ├── color-palette/
│ ├── color-block/ # typed/heterogeneous blocks (addMenu discriminator)
│ ├── dynamic-layout/
│ ├── tool-logo/ # "Logo" - auto-switching brand logo
│ ├── street-map/ # offline vector city-block maps
│ ├── url-shot/ # "URL Screenshot" (capture capability)
│ ├── strip-data/ # on-device metadata strip - JPEG/PNG/SVG/PDF (file in → clean file out)
│ ├── compress-pdf/ # on-device PDF compressor - recompresses images (file in → smaller file out)
│ ├── brand-lockup/ # "Brand Lockup" - SUSE logo lockups; HarfBuzz text-to-path (wasm)
│ ├── chart-creator/ # SVG charts from structured data
│ ├── filter/ # photo effects in one tool - halftone/scanline/posterize/voronoi (vector), duotone/pixel-stretch/imperfections (raster)
│ ├── meeting-planner/ # global timezone meeting scheduler
│ ├── calendar-ics/ # event → .ics calendar file plus a card
│ ├── digi-ad/ # "Animated Ad" - looping banner from scenes
│ ├── event-name-badge/ # conference badges - composes qr-code as an SVG
│ ├── wayfinding-signage/ # event signage; directions blocks auto-fit label text
│ ├── text-helper/ # on-device text workbench (format/decode/hash/de-identify)
│ ├── design/ # "Design" - freeform WYSIWYG editor canvas (render.layout: editor)
│ ├── multi-page-pdf/ # multi-page PDF document - cover, flowing content blocks, back page
│ ├── diagram-builder/ # org / layercake / process / cycle / pyramid diagrams
│ ├── logo-wall/ # many logos → auto-packed grid
│ ├── logo-lockup-partner/ # SUSE + partner co-brand lockup
│ ├── icon/ # favicon .ico / png / svg from text + colours
│ ├── lottie-digi-ad/ # animated Lottie ad banners
│ └── pose-geeko/ # pose the SUSE Geeko mascot - print-ready stills
│
├── catalog/
│ ├── tools/index.json # tool registry
│ └── assets/
│ ├── index.json # asset registry
│ └── suse/... # logo, palette, etc.
│
├── schemas/ # JSON Schema for tool.json, asset entries, AssetRef
├── scripts/ # build-catalog-index.ts, checksum-assets.ts, validate-catalog.ts
├── tests/ # engine tests
└── docs/ # this file + authoring guides + positioning
Модел на доставка на платформата
Платформата работи на няколко повърхности - уеб PWA, Tauri настолна/мобилна версия, скриптируемия CLI и интерактивния TUI. Всички те използват един и същ двигател и едни и същи файлове с инструменти.
Уеб (PWA) - основно разпространение
Хостван на URL, контролиран от SUSE. Работи офлайн, след като service worker-ът е кеширал инструментите и активите. Тук повечето служители, доставчици и партньори ще използват платформата. Не се изисква акаунт - състоянието се съхранява в IndexedDB на всяко устройство.
Уеб обвивката е адаптивна от едно единствено оформление. На настолен компютър инструментът е странична лента с контроли с променлив размер до сцена за преглед с навигация на платното, родна за тракпад (Cmd/Ctrl-колело или щипване за мащабиране около курсора, Space- или средно провлачване за преместване, клавиши 0/1/+/− и HUD за Fit/%). На мобилно устройство (≤640px) контролите стават лист, закачен отгоре, с плъзгаща дръжка, която прещраква между peek/half/full (докосването превключва) над статичен преглед на цял екран, а плаващ бутон Render отваря контролите за Export в изскачащ лист отдолу. Докосването получава щипване за мащаб и провлачване за преместване върху прегледа. Пътят на рендиране и контролите за експортиране са идентични и в двата случая - само хромът се преподрежда.
signed by Lollyvector SVGПровери самGet the signed file5 paths989 nodes11 groups14 KB
signed by Lollyvector SVGПровери самGet the signed file5 paths989 nodes11 groups14 KB
Същият инструмент при ширина на телефон, без втори layout за поддръжка: контролите стават лист в горната част, прегледът заема целия екран, а хапчето за рендиране плава над него.
signed by Lollyvector SVGПровери самGet the signed file47 paths~1.9k nodes84 groups1 image212 KB
signed by Lollyvector SVGПровери самGet the signed file47 paths~1.9k nodes84 groups1 image211 KB
Режим Batch (/pro). Уеб обвивката предлага и таблична batch мрежа (shells/web/src/pro/), която рендира много редове наведнъж през един или няколко инструмента. Тя поддържа кръгова обработка на CSV/TSV плюс поставяне от таблица, шаблон/формат/размер/мерна единица/dpi за всеки ред, страничен панел с редактор на блокове с преглед на живо, свиваеми колони за експорт, лента с етикети „relevance“ за всеки ред, преподреждане на редове чрез плъзгане с ляв манипулатор, двустъпково потвърждение за изтриване, запазени batch сесии и изтегляне на .zip. Това е повърхността „едно към много“ зад позиционирането „масово генериране на съдържание“.
Tauri desktop / mobile
Опакован нативен app (малък отпечатък чрез Tauri). Осигурява пълна офлайн наличност, достъп до файловата система за инструменти, зависими от CLI (PDF Smasher, Font Outliner), и достъп до камерата. Планирано подобрение на инструментите за средата на 2026.
CLI
lolly <tool-id> [--input=value ...] --output=file.png
Потребителите на десктоп могат да извикват много инструменти от терминала. CLI обвивката зарежда същия engine, създава jsdom DOM, изпълнява същия render път и записва файла. URL режимът е транспортът - CLI не е отделна реализация. Това гарантира, че изходите на CLI и GUI са идентични.
lolly qr-code --url=https://suse.com --output=qr.svg
lolly quotes --quote="Ship it." --output=quote.png
lolly # lists available tools
lolly qr-code # lists inputs for that tool
TUI
npm run tui
Интерактивният аналог на CLI: терминален app на цял екран, ориентиран към клавиатурата (изграден върху Ink), за преглед на инструменти, попълване на входове, запазване на проекти и експортиране - всичко без GUI. Неговият host bridge преизползва реализацията на CLI за форматите без DOM (SVG/EMF/EPS/HTML + текст/данни) и добавя състояние на диска под ~/.lolly плюс изричен вграден преглед. Освен това има ниво за рендиране в браузър: обхванат headless Chromium (същият, който MCP сървърът инсталира), който произвежда растер/PDF/видео и заснемане на живи URL адреси при поискване - задвижвайки изградено копие на уеб обвивката, така че изходът е идентичен, и стартиращ само при първия ви експорт в такъв формат. Така url-shot (с изрязване + прецветяване + векторен PDF/SVG) и всеки растер/pdf инструмент работят и в терминала. Вижте ръководството за TUI.
На каквато и повърхност да сте, разделът Capabilities в таблото е пълната карта на това, което платформата декларира, че може да прави, групирана и четлива без да отваряте нито един инструмент.
Категории инструменти
Инструментите се маркират с category в манифеста си за групиране в галерията.
Редовете са изброени в реда на секциите в галерията. Секцията utility винаги се рендира последна в галерията (след всяка друга категория, включително бъдещи) - това е локалното (on-device) чекмедже „Offline Utilities“.
| Категория | Примери | Планирано |
|---|---|---|
everyone | QR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence Studio, Record | Employee Image Stationery |
designer | Brand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, Multi-Page PDF | 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 Helper, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL Screenshot | Unit/format converters, more on-device privacy utilities |
Тези клетки са примери, не пълен опис. Кои инструменти съществуват е свойство на профила, който сте монтирали, не на тази страница: пакет с марка добавя свои собствени и може да изключи инструмент от общността, който не желае да разпространява. catalog/tools/index.json - генериран от манифестите и регистърът, който галерията реално чете - е авторитетният списък; за да преброите какво монтира даден профил, преброете манифестите (ls community//tool.json brands//tools/*/tool.json), вместо да се доверявате на число, записано тук. (Идентификатор на инструмент, присъстващ в два пакета, се монтира само веднъж, от печелившия пакет.)
Инструментите се класифицират и по статус: official (одобрен от марката, без воден знак), community (принос от общността), experimental (експортите носят воден знак). По-голямата част от библиотеката е official; по-новите студиа и инструментите за заснемане обикновено се намират в community или experimental, докато се стабилизират. Всяка повърхност показва баджа, така че читателят знае какво получава, преди да го отвори - и, както при клетките с категории по-горе, принадлежността по статус се променя твърде бързо, за да бъде изброена тук. Проверете я в галерията или в генерирания индекс.
Design е първият инструмент, изграден върху режима на свободно платно render.layout: "editor" - повърхност без chrome, с директна манипулация, където плъзгате, преоразмерявате, завъртате и подравнявате чрез snap кутии с текст, форми и изображения, след което експортирате през същия render път като всеки друг инструмент.
Strip Hidden Data е първата локална (on-device) утилита (privacy: "on-device"): инструмент за трансформация на съдържание, който взима файл, предоставен от вас, обработва го изцяло в браузъра и връща чисто копие - никога не се качва, никога не се маркира с воден знак, не се подпечатва произход. Text Helper е вторият - работно място на устройството за ежедневни задачи от типа „постави в сайт“ (форматиране на JSON, декодиране на JWT, Base64, URL кодиране/декодиране, SHA хеширане). Compress PDF е третият - той свива PDF, като прекомпресира изображенията в него, отново изцяло на устройството. Маркерът и текстът на баджа му "Runs on your device - nothing is uploaded" вече покриват целия набор от трансформации: Strip Hidden Data, Text Helper, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (унищожава области от изображение, SVG или PDF), Prompt to Image и Rebrand a Deck (променя темата на .pptx на място), където профилът я монтира. Това е категория утилити за поверителност, която заменя предаването на поверителни файлове на сайтове с единствено предназначение.
signed by Lollyvector SVGПровери самGet the signed file154 paths~40k nodes234 groups802 KB
signed by Lollyvector SVGПровери самGet the signed file154 paths~40k nodes234 groups803 KB
Забележка:
categoryиstatusсе денормализират вcatalog/tools/index.json(регистърът, който галерията чете) от всекиtool.json. Манифестът е източникът на истина - индексът е генериран отnpm run build:catalog, аnpm run validate:catalogпроваля CI, ако включеният индекс се разминава с манифестите.
Архитектурни ангажименти
Тези решения са установени. Промяната на всяко от тях е мащабно начинание - те оформят всяко друго решение в кодовата база.
1. Декларативни инструменти, с императивен изход при нужда
Инструментът е манифест (tool.json) + шаблон (template.html) + по избор hooks.js.
Манифестът декларира входовете. Не шаблонът. Входовете не се извеждат от Handlebars токени. Манифестът е договорът; шаблонът консумира именувани променливи чрез {{id}}.
signed by Lollyvector SVGПровери самGet the signed file39 paths~3.4k nodes70 groups2 images50 KB
signed by Lollyvector SVGПровери самGet the signed file39 paths~3.4k nodes70 groups2 images50 KB
Hooks са по избор. Повечето инструменти са чисто декларативни - манифест + шаблон е достатъчно. Инструментите, нуждаещи се от изчислени стойности (QR кодиране, оформяне на данни за графики), предоставят hooks.js, който излага именувани функции от жизнения цикъл (onInit, onInput, onFrame - hook за всеки кадър при жива камера за реагиращи на движение инструменти - onLevel, beforeExport, afterExport, exportFile - пътят на трансформация файл-влиза/файл-излиза, използван от локални утилити като Strip Hidden Data - и exportStill, за инструмент, който притежава собствен дълбок растер). Host зарежда hooks чрез new Function('host', …), с инжектиран capability bridge като closure scope. Това е договор за преносимост, не защитна пясъчна кутия (sandbox): hooks все още се изпълняват в реалма на страницата и могат да достигнат до window/fetch/document в браузърна обвивка - host. е поддържаната, преносима повърхност, а не наложена граница. Резултатите от асинхронни hooks са ограничени във времето (onInit 5с, onInput 2с, beforeExport/afterExport 5с, exportFile/exportStill 10с), а закъснелите резултати се отхвърлят; неконтролируем синхронен* hook не може да бъде прекъснат. Затова изпълнението на недоверен hook код от трети страни не е безопасно, докато не се появи изолация чрез Worker.
Това има значение, защото: декларативните инструменти могат да се създават от хора без разработчически опит. Ако всеки инструмент беше уеб приложение, рисковата бележка „ограничени умения за създаване/поддръжка на работни шаблони“ се превръща в постоянно тясно място.
2. Инструментите и активите са данни, не пакетиран код
Уеб и Tauri приложенията извличат каталозите с инструменти и активи от известен URL адрес при стартиране, кешират ги локално и работят с каквото има там. Добавянето на нова плочка за събитие или сезонен актив не изисква release на приложението.
Байтовете на активите се контролно сумират с SHA-256, за да се предотврати CDN отравяне. id + version на актива задвижва обезсилването на кеша.
3. Capability Bridge е единственият API, който инструментите виждат
Инструментите никога не докосват DOM извън областта на своя шаблон, никога не викат fetch директно, никога не четат файловата система. Те викат версионирани методи host.*. Каноничната дефиниция на договора е packages/core/src/host-v1.ts - SDK за автори на инструменти @lolly-tools/core, така че трета страна може да разработва спрямо него без зависимост от engine; engine/src/bridge/host-v1.ts е type re-export на него, а кодът на engine/shell продължава да импортира от този път без промяна:
| Bridge API | Какво прави |
|---|---|
host.profile | Собствено име, имейл, снимка, град на потребителя и др. Предварително попълва входове чрез bindToProfile. |
host.assets | Заявки към каталога, разрешаване на активи, UI за избор, предоставен от host. |
host.state | Запазване / зареждане на входни слотове. IndexedDB в уеб, файлова система в Tauri, памет в CLI. |
host.clipboard | Записва текст или изображение в клипборда (с резервни варианти за платформата). |
host.export | Растеризира или сериализира целта на рендиране. Прилага воден знак за експериментални инструменти. |
host.net | Fetch с allowlist - достъпен само ако инструментът е декларирал capability "network". (Никой публикуван инструмент не го използва в момента.) |
Опционалните, добавъчни повърхности се появяват само когато обвивка ги предоставя. Някои са обвързани с capability - изложени само когато инструментът декларира съответния флаг: host.compose (вгражда рендирането на друг инструмент - compose), host.capture (заснемане на страница за URL Screenshot - capture) и host.recorder (заснемане от микрофон/камера/екран за инструментите за запис - microphone / camera / screen). Останалите се откриват по функционалност - присъстват, когато обвивката може да ги предостави, като инструментът пази резервен вариант за обвивки, които не могат.
Няколко водещи повърхности, за да покажем какво покрива - Host API документира всяка от тях, а packages/core/src/host-v1.ts е самият договор:
| Повърхност | От версия | Какво добавя |
|---|---|---|
host.tokens | 1.0 | DTCG дизайн токени - собствените примитиви на бранда |
host.text | 1.0 | Текст в път чрез HarfBuzz WASM (флагът за възможност wasm маркира инструментите, които разчитат на него) |
host.media | 1.4 | Живи кадри от камера, задвижващи хука onFrame. Прогресивно подобрение, съзнателно не ограничено от флага camera - такъв инструмент все още работи като обикновен инструмент за неподвижни изображения |
host.color | 1.40 | Перцептивна цветова математика: ΔEOK, контраст WCAG + APCA, OKLab рампи, разбивки на класове, категорийни палитри, хармонични схеми (1.60), смесване по CSS Color 4 и печене на градиенти (1.68). Чиста и синхронна - обвивките прикачват makeColorApi() на двигателя, вместо да реализират каквото и да е, затова не може да се разминат |
host.images | 1.60 | Декодиране/преоразмеряване/прекодиране на байтове на устройството - пътят за конвертиране (HEIC → JPEG, компресиране до WebP, намаляване на мащаба). Доставен в уеб обвивката като „мързелива“ фасада, затова HEIC декодерът никога не влиза в стартовия чънк |
host.geom | 1.64 | Точна векторна геометрия: булеви операции над пътища, отместване, преобразуване на щрих в заливка, снижаване на сплайни, опростяване, проверка за попадение. Също чиста, синхронна и прикачена от двигателя (makeGeomApi()); грешките се връщат, никога не се хвърлят |
Останалите следват същите правила и са документирани заедно с тях: pdf (1.8) и pptx (1.58) за локална хирургия на документи, audio (1.71) и speech (1.96) за анализ на клипове и локален TTS/транскрипция, viz (1.72) за договора-заместител на MilkDrop, codec (1.100) и layers (1.102) за изход с дълбок бит и слоести растерни изображения, upscale (1.101) и matte (1.103) за локалните модели, raster (1.105) за hooks, които вършат собствена пикселна работа, connectors (1.106) за безопасни за експорт стрелки и c2pa (1.85) за подписване на готови байтове. Броят расте; правилата - не.
Декларируемите capabilities са: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, добавен в 1.54, е заснемане на екран чрез host.recorder - потребителят избира екран/прозорец/раздел в нативен за браузъра UI; отличава се от capture, който растеризира URL адрес, посочен от самия инструмент.)
Един и същ инструмент работи в браузър, Tauri и headless CLI, защото всяка обвивка имплементира този интерфейс - инструментът никога не знае в коя се намира.
Bridge-ът е версиониран. Добавянето на методи е минорна версия. Премахването или промяната на сигнатури е major версия. Когато излезе v2, v1 трябва да продължи да работи.
4. Идентификаторите на активи са завинаги
suse/logo/primary е договор. След публикуване:
- ID никога не се променя, никога не се преизползва.
- Промени в байтовете → повишете
versionв манифеста. - Заменен от нов актив → задайте
deprecated: trueи по изборreplacedBy. - Съществуващите препратки винаги се разрешават.
Това прави запазените състояния на инструменти и споделените чрез URL връзки трайни през годините.
5. URL режимът е първокласен
Всеки вход трябва да може да се изрази като URL параметър:
lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H
signed by Lollyvector SVGПровери самGet the signed file17 paths~2.0k nodes39 groups24 KB
signed by Lollyvector SVGПровери самGet the signed file17 paths~2.0k nodes39 groups24 KB
Режимът CLI е URL режим под друг транспорт - CLI обвивката изгражда обект на URL състояние от argv и изпълнява същия engine pipeline. Има само един render път. CLI не може да се разминава с GUI, защото не е отделна реализация.
url-mode.ts управлява кръговата обработка (parse и serialize). Набор от резервирани параметри никога не се препращат към инструмента като входове: контролите за изхода (format, export, copy, filename, width/w, height/h, unit, dpi), регулаторите за печат и произход (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) и носителите на състояние (template, z - опакованият токен „Shortest link“ - и zx, същият, криптиран с парола). Наборът RESERVED в engine/src/url-mode.ts е авторитетният източник и е фиксиран с тест; URL Mode документира всеки от тях, включително няколкото, които не са изброени тук. Входовете от тип актив в URL режим се сериализират по своя id; runtime ги разрешава чрез host.assets.get() преди хидратация. width/height са стойности в unit (по подразбиране px, също mm/cm/in/pt/pc); при физическа единица dpi задава резолюцията за растер. Те задават размера на документа на платното и предварително попълват панела с размери за експорт.
Тъй като всеки вход пътува във връзката, промяна на параметър е различен готов актив. Цялата тази палитра е един начален цвят, хармония и брой стъпки:
signed by Lollyvector SVGПровери самGet the signed file10 groups24 KB
signed by Lollyvector SVGПровери самGet the signed file10 groups24 KB
6. Съхранението минава през моста, не директно
Уеб обвивка: IndexedDB. Tauri: файлова система. CLI: в паметта. Инструментите виждат само host.state.save(slot, data) и host.state.load(slot). localStorage не се използва - твърде малък е и не може да съхранява blob-ове.
Потребителите могат да записват няколко именувани слота за редакция на инструмент и да се връщат към всяка сесия по-късно. Не се изисква създаване на акаунт; състоянието е по устройство. Тъй като мостът е единствената точка на достъп, това състояние по устройство е и преносимо: shells/web/src/data-transfer.ts изчита всичко обратно през host.profile/host.state/host.assets в един zip lolly-backup, който се импортира на всяка друга инсталация - офлайн отговорът на "преминаване към ново устройство", без нужда от сървър (пълна спецификация: docs/data-transfer.md). Интеграцията със SUSE ID (синхронизация между устройства) е бъдещ етап върху тази основа.
7. Етикетите за зрялост отговарят на риска "одобрено от бранда" по дизайн
Всеки инструмент декларира status: official | community | experimental в манифеста си. Галерията сортира по статус. Експерименталните инструменти автоматично поставят воден знак на изнесеното съдържание - водният знак се прилага от host.export.render, не от инструмента, така че не може да бъде изключен от автор на неофициален инструмент.
Това е структурен отговор на риска от възприятие, че използването на който и да е инструмент означава одобрение от бранда. Процесни отговори (опашка за преглед, ограничение чрез SUSE ID) се надграждат отгоре.
8. Входовете на инструментите се типизират чрез манифеста, включително активите
Входовете декларират type: text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table и file. Хостът рендира генеричен контрол за всеки тип от манифеста - инструментите не пишат код за контроли. (Предварителното попълване от профила на потребителя не е тип - всеки вход може да носи bindToProfile.) Три от тях носят повече тежест от останалите:
asset(сfilterиallowUpload) е мостът към глобалната система за активи;allowUpload: falseе лостът за налагане на бранда за неща като лога на спонсорски плочки, където се допускат само активи от библиотеката. Качванията от потребителя използват същата формаAssetRefкато активите от библиотеката, така че инструментите ги обработват еднакво.blocksе повтарящa се група от полета - мини-таблица вътре в един вход, редактирана в странична панел, с типизирано/дискриминирано меню за добавяне и полета за активи по блок. Кликването върху рендиран блок в канваса фокусира съответния ред. Използва се отmeeting-planner,chart-creator,event-name-badge,wayfinding-signage,color-blockиdigi-ad.vectorгрупира фиксиран набор от числа (напр. трансформация) в един съставен контрол;fileсъхранява собствения файл на потребителя като байтове в паметта за инструменти за трансформация на устройството (напр.strip-dataиcompress-pdf).
9. Шаблоните са без логика (Handlebars, не EJS)
Handlebars е избран пред EJS съзнателно:
- Без логика. Шаблоните могат да се създават от хора, които не са разработчици.
- Безопасен по подразбиране.
{{x}}escape-ва HTML;{{{x}}}е незадължителна суровина. - Липсата на произволен JS в шаблоните означава липса на повърхност за одит на XSS за всеки шаблон.
Логиката живее в hooks.js, където е явна и подлежаща на преглед. Налични помощници на Handlebars: {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (плюс помощници за формат на данни icsStamp/rfcText/csvCell, използвани от съседните шаблони .ics/.vcf/.csv).
10. Инструментите съставят инструменти
Инструмент може да вгради рендера на друг инструмент без импорти между инструментите - композицията се разрешава от двигателя, никога от кода на инструмента. Има две повърхности:
- Декларативен манифест -
composes: [{ id, tool, inputs, format?, width?, height? }]. Двигателят рендира именувания дъщерен инструмент и поставя резултата в шаблона без логика като{{asset <id>}}.event-name-badgeсъставяqr-codeкато SVG днес. - Преносим вграден URL -
<img src="https://lolly.tools/tool/<id>.<ext>?<inputs>">. Обвивката рендира този дъщерен инструмент локално (плейсхолдър пиксел се показва, докато локалният рендер се разреши); нищо никога не се извлича отlolly.tools.
Съставяне на рендера на всеки инструмент: дъщерен SVG остава истински вектор, когато родителят изнася в SVG или PDF, и се растеризира чисто за PNG; дъщерни PNG/JPG/WEBP се вграждат като изображения. Изисква способността compose. Съставените дъщерни елементи са междинни - никога не носят воден знак или печат за произход - и композицията се деградира плавно: обвивка, която не може да рендира дъщерен елемент, просто пропуска слота, а родителят пак се рендира.
Какво съзнателно избрахме да не правим
- Без EJS / без произволен JS в шаблоните. Повърхността за XSS е нулева. Логиката живее в
hooks.js. - Без задължителна CMS за активи. Отделните хора внасят собствените си творчески файлове направо в каталога си вътре в приложението (изгледът Каталог и Brand Studio) - без сървър, без административна конзола. Работата се предава нататък като сесия: връзка за споделяне носи цялото състояние, а същата сесия пътува в резервно копие или през сесия за съвместна работа. Който контролира внедряването, може после да заключи споделена сесия като шаблон - отваря връзката, записва стойностите ѝ като запис на шаблон в директорията на този инструмент в пакета за бранда и прави commit - след което тя се появява в избирача „New from template“ на инструмента и може да се достига чрез директна връзка като
?template=<id>. Git е стъпката за заключване на собственика на внедряването, никога на автора. За споделен, управляван каталог, организация може да управлява директорията с активи по същия начин и да блокира актуализациите чрез PR преглед - наличен модел на управление, а не изискване на приложението. - Без наложен RBAC. Отвореното приложение е публично достъпно по подразбиране; рискът за бранда се управлява с етикети за зрялост + водни знаци. Организация, която иска по-строг контрол, наслагва собствена автентикация и прегледания в git каталог по-горе.
- Без централна база данни. Цялото потребителско състояние е на всяко устройство поотделно. Интеграцията със SUSE ID е в пътната карта, но не е пречка за пускането.
- Без общ път на кода за инструменти/енджин. Енджинът е с отворен код, както и брандово-независимите инструменти в
community/; пакет за бранд като частнияbrands/suse/носи собствените си инструменти и каталог по свои собствени условия. И в двата случая разделянето е наложено (без кръстосани импорти отengine/в съдържанието на инструментите), така че разделението остава чисто.
Жизненият цикъл, от начало до край
Потребител отваря lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H:
- Зареждане. Уеб обвивката отваря IndexedDB, конструира моста от способности, синхронизира каталозите на инструменти и активи (или зарежда от кеш при офлайн).
- Маршрутизация. URL хеш → изглед
tool, с извлечениqr-codeи URL параметри. - Зареждане.
loadTool('qr-code', fetchFile)извличаtool.json, валидира спрямо JSON схема, извличаtemplate.html,styles.cssи изходния код наhooks.js. - Разбор на URL състоянието.
parseUrlStateпревръща URL параметрите в начални стойности на входовете. Референции към активи (?logo=suse/logo/primary) се разбират като леки обекти{ id, _unresolved: true }. - Изпълнение.
createRuntime(tool, host, initialValues)изгражда модела на входовете (сливайки данни от профила, стойности по подразбиране и начални стойности), разрешава референции към активи чрезhost.assets.get(), зарежда хуковете (сhostв затворен обхват, не в пясъчник), извикваhooks.onInit. - Рендиране. Обвивката се абонира за изпълнението; при всяка промяна на състоянието получава
{ model, hydrated }. Тя рендира контролите за входовете от модела и записва хидратирания HTML на шаблона в#tool-canvas. - Взаимодействие. Потребителят пише в поле за вход →
runtime.setInput(id, value)→ прилагат се ограничения → извиква сеhooks.onInput→ повторна хидратация → повторно рендиране. Канвасът се обновява на живо. - Изнасяне. Потребителят кликва Download(PNG) →
runtime.export(canvasNode, 'png')→host.export.render(растеризира чрез dom-to-image-more; SVG/PDF минават през специализирани векторизатори, обхождащи DOM) → blob →host.export.download. Диапазонът от формати, които инструмент може да избере, е широк, а изброяванетоrender.formatsвschemas/tool.schema.jsonе авторитетният източник за него - растери и плаващи растери, вектори и файлове за рязане, печат/CMYK, движение, редактируеми документи (pptx,docx,odt), палитра и изходи за данни/текст, аудио и файлове с шрифтове. URL режим назовава всеки идентификатор и какво произвежда. Аудиото е в това изброяване както всичко останало (wav,mp3,m4a,opus, декларирани от аудиограмата и инструментите за запис); отделно, режимrender.captureна инструмент за запис задвижваhost.recorder, чийто запис пристига като завършен Blob в контейнера, в който браузърът е записал. (Инструменти, които задаватrender.export: false- напр. Color Palette, Countdown Timer, Strip Hidden Data, Text Helper, Compress PDF - скриват контролите за изтегляне/формат/размери.) Физическите единици се преобразуват за всеки формат тук (PDF → истински пунктове на страницата, растер → пиксели при DPI с блокpHYs). Метаданните за авторство/произход (автор, инструмент, източник - изградени отengine/src/metadata.ts) се вграждат за всеки формат: PNG iTXt, JPEG EXIF, PDF info dict, SVG<metadata>, GIF коментар. Експерименталните инструменти получават воден знак, поставен от хоста, не от инструмента.
signed by Lollyvector SVGПровери самGet the signed file49 paths~3.3k nodes61 groups3 images74 KB
signed by Lollyvector SVGПровери самGet the signed file49 paths~3.3k nodes61 groups3 images74 KB
Същият жизнен цикъл в Tauri. Същият жизнен цикъл в CLI - jsdom осигурява безглав DOM; изходът отива във файл или stdout.
Статус на отворения код
Кодът е MPL-2.0. engine/, shells/, services/, schemas/ и docs/ са с отворен код под MPL-2.0 - платформа за скелетна структура (scaffolding), неутрална към доставчици, за брандови инструменти, като всяка доставяна единица е в собствено хранилище под github.com/lolly-tools.
Съдържанието на инструментите се доставя като пакети за бранд, всеки със собствени условия (виж NOTICE.md на пакета). community/ е публичното хранилище lolly-tools и неговите брандово-независими инструменти също са MPL-2.0. brands/suse/ е частният пакет suse-lolly: инструментите на SUSE и каталогът на SUSE, собственост на SUSE, включително лицензираната му музика PremiumBeat. brands/lolly-start/ е празният стартов бранд, притежаван от това хранилище. Шрифтовете се доставят вътре в пакет под SIL Open Font License 1.1 - пакетът на SUSE носи шрифтовете SUSE и SUSE Mono.
tools/ и catalog/ в корена на хранилището са игнорирани от git изгледи: профил ги събира от community/ плюс активния пакет за бранд, затова всеки скрипт и обвивка четат тези два пътя, а никога пакет директно.
Разделянето е наложено - няма кръстосани импорти от engine/ в съдържанието на инструментите - така границата между платформа и съдържание остава чиста.
Къде свършва двигателят и започва хостът
Ако можеш да го опишеш с чисти данни + Handlebars → двигател. Ако засяга DOM, файловата система, мрежата или API на браузър/ОС → хост.
Границата е рязка нарочно. Двигателят е частта с отворен код. Всичко, което знае за SUSE, конкретни платформи или среди на изпълнение, остава извън него.
За следващото ниво на детайл, engine/README.md изброява всеки модул на двигателя и за какво отговаря, а Модел на заплахите и граници на доверие документира къде тази същата граница едновременно служи като граница на доверие.