Цей документ фіксує мету, структуру та архітектурні рішення платформи Lolly. Він відображає як бачення продукту, так і поточний стан кодової бази.
Статус: Lolly випущено. Версія 1.0 вийшла з відкритим кодом під MPL-2.0 30 серпня 2026 року, а можливості, типові значення та каталог інструментів і далі змінюються між випусками. Двигун детермінований, і за кожною оболонкою стоїть один шлях рендерингу. Його безпека ще не пройшла незалежного аудиту, а докази впровадження мають кілька місяців. Про поточний стан і те, як вимірюється впровадження, див. Впровадження та управління.
Як читати цю сторінку. Вона містить два види матеріалу, за порядком. Перша половина - це навіщо це існує: проблема, позиціювання і життєвий цикл, через який проходить один актив. Від Загальна картина і далі йде як складаються шари: архітектурний документ для контриб'юторів, що охоплює розділення engine/shell/pack, структуру репозиторію, цілі постачання та зобов'язання, що обмежують кожну зміну платформи. Якщо ви тут, щоб змінювати кодову базу, а не щоб зрозуміти продукт, почніть із загальної картини.
Два супутники йдуть глибше за цю сторінку.
engine/README.mdу репозиторії - це карта двигуна модуль за модулем, зі згенерованою таблицею кожного модуля і того, що він розбирає чи записує. Модель загроз і межі довіри - та сама архітектура, прочитана як межі довіри, і це правильна сторінка для будь-якого питання про те, що двигун вважає недовіреним.
Навіщо це існує
Повторювана творча робота надто передбачувана, щоб щоразу виправдовувати залучення кваліфікованих рук, і надто чутлива до якості, щоб передавати її без запобіжників. Залишена сама на себе, вона йде одним із трьох шляхів: повільно, неузгоджено або замкнено в шаблонах постачальника.
Ця платформа - пряма відповідь:
Програмний творчий і контентний вивід у масштабі - генерація активів із вхідних даних, з правилами, встановленими один раз, для тих, кому вони потрібні.
Lolly — це не те місце, де вигадують дизайн-систему, а те, де її виробляють. Уявіть це як торговельний автомат для дизайну: робите вибір — отримуєте результат. Щоразу. Рушій працює на найвищу якість, яку кожен формат здатен видати на обладнанні перед вами, і той самий рушій створює той самий файл на кожній платформі, куди він постачається.
Результат - достаток: кожна подія має правильні вивіски, кожне сповіщення про CVE відповідає фірмовому стилю, кожна етикетка друкується чисто, кожен email-підпис актуальний - усе з інструментів, що вже несуть ці правила. Платформа обробляє повторювану операціоналізовану творчість. Це навмисно не інструмент для унікальної творчої роботи - дизайнери й далі володіють флагманською роботою.
Досліджуйте ймовірнісно, масштабуйте детерміновано
Кожна суперечка про ШІ в творчому конвеєрі впирається в те саме питання: яка частина цього - робота машини? Це старе питання з усталеною відповіддю. Переписувачі й ілюстратори вже працювали між двома інструментами - вільним ескізом, де нічого не було фіксованим і все можна було пробувати, і друкарським верстатом, лячним саме тому, що він фіксував остаточно. Ескізи - це де відбувалося мистецтво. Верстат - це як воно доходило до когось. Ніхто не плутав ці дві речі, і обидві продовжували розвиватися - нові чорнила, нові шрифти, нові верстати - кожна вдосконалювалася в гармонії з ремеслом і задумом, якому служила.
Lolly проводить ту саму межу. Досліджуйте ймовірнісно: модель, дизайнер, груба ідея, підказка, що веде туди, куди ніхто не планував. Потім масштабуйте детерміновано - те, що перетворюється на багато виводів, це інструмент, а інструмент рендериться однаково щоразу з вхідних даних, які можна прочитати. Дослідження лишається вільним, бо нічого нижче за течією не залежить від того, чи вийде воно однаково двічі. Вивід заслуговує довіри, бо це не здогадка. Перетворення експериментів зі ШІ на передбачувані, відтворювані результати - не нова дисципліна; це той самий розподіл праці, що зробив друковану роботу вартою довіри від самого початку.
Довіряйте творчому процесу, масштабуйте зі строгістю.
Проти альтернатив
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 |
Повнота можливостей серед сьогоднішніх творчих інструментів, досліджено у серпні 2026. Оцінка: 0 відсутнє, 25 рівень обхідного рішення, 50 реальне, але обмежене або часткове, 75 сильне з застереженнями, 100 основна компетенція.
signed by Lollypositioning-comparison.htmlHTMLpixels, not shapes40 KBAI generatedgenerated by GPT-6Перевірте саміОтримати підписаний файлРозрив очевидний: ніщо з того, що постачається сьогодні, не дає нам вивід constraints-first, придатний для офлайну, з низьким порогом навичок, внутрішньо доступний. Lolly навіть включає відкрите полотно - Design - де кольори, шрифти та активи узгоджуються з глобальними параметрами бренду, тож вільне компонування лишається constraints-first. Чим воно не є - це необмеженим дизайн-пакетом: дизайнери й далі використовують Illustrator і Figma для унікальної флагманської роботи. Перестановки можна складати цим інструментом.
signed by Lollyvector SVG367 paths~62k nodes773 groups3 images1 453 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG367 paths~62k nodes776 groups3 images1 454 KBПеревірте саміОтримати підписаний файл
Використовуйте для: Швидка генерація операціоналізованих творчих активів - плиток подій, бейджів з іменами, підписів, сповіщень про CVE, QR-кодів, соціальних карток, етикеток вантажів, структурованих звітів.
Не використовуйте для: Унікального флагманського контенту.
Життєвий цикл кампанії
Найясніший спосіб побачити, чим є Lolly, - не список функцій, а простеження одного активу, коли він переходить з рук у руки. Спостерігайте, як одна локалізована картка кампанії рухається через організацію:
- Творча особа встановлює правила. Дизайнер створює базовий шаблон в інструменті Design, жорстко закодовуючи типографіку й колірні змінні бренду. Вони роблять не одну картку - вони виконують основоположну роботу один раз, щоб більше ніколи не локалізувати її вручну.
- Розробник масштабує це. Той самий шаблон підключається до нічного конвеєра через CLI, тож свіжий графік чи нова мовна варіація генерується автоматично - жоден дизайнер не відкриває файл повторно.
- Продюсер просто користується цим. Торговий представник, офлайн у літаку, відкриває той самий інструмент і генерує ідеально відповідну бренду презентацію для зустрічі з клієнтом. Без дизайнерських навичок, без мережі, без очікування.
«Свіжий графік» на кроці два - це рендер на кшталт цього, вироблений з рядка даних і жменьки параметрів без відкривання файлу дизайну кимось:
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBПеревірте саміОтримати підписаний файл
Суть не в тому, що Lolly добрий для дизайнерів і добрий для розробників і добрий для продажів, кожен окремо у вакуумі. Це естафета: початкову роботу творчої особи масштабує розробник, що своєю чергою дає можливості продюсеру. Легкий досвід для нетехнічного представника в літаку можливий лише завдяки строгості, яку встановив дизайнер і розгорнув розробник.
Це і є множник сили. Lolly - не шухляда окремих інструментів для окремих ролей - це один детермінований життєвий цикл активу, якого торкається кожна роль, і кожна пара рук, через які він проходить, множить цінність попередньої.
Один інструмент, багато виводів
Правила бренду живуть в інструменті, а не в кожному файлі, який він створює (див. Як Lolly порівнюється). Налаштуйте інструмент правильно один раз - і кожен вивід успадковує той самий шрифт, колір і відступи, чи то одна картка, чи таблиця рядків десятком мов. Як ви перевіряєте свою роботу і хто це робить - залишається за вами; Lolly зменшує те, що варто перевіряти, і пришвидшує вивід.
Той самий детермінований інструмент досягає цього масштабу трьома способами, і всі виробляють ідентичний вивід:
- Людина, у застосунку. Пакетна сітка
/pro: вставте або імпортуйте рядки, отримайте один готовий актив на рядок, завантажте zip. Без дизайнерських навичок, без очікування. - Розробник, з командного рядка. CLI запускає той самий двигун і той самий шлях рендерингу без інтерфейсу, тож інструмент можна послідовно застосувати до кожного рядка у скрипті чи нічному конвеєрі. Виклик
lolly <tool> --field=…у циклі - це вся інтеграція. - Система або агент ШІ, через MCP. Той самий інструмент, керований програмно, з тією самою точністю - для стількох рядків, скільки їх у завданні.
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 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 │
└─────────────────────────────────────────────┘Структура репозиторію
Lolly - це один репозиторій. engine/, schemas/, scripts/, tests/, api/, docs/, community/, brands/lolly-start/, кожен shells/ і обидва services/ - це звичайні каталоги в ньому. Єдиний виняток - brands/suse, приватний git-підмодуль, що містить набір інструментів SUSE та каталог, опційний і відсутній у публічному клоні. Які пакети читає конкретна збірка, визначає профіль вмісту (profiles.json), що вирішується для кожного процесу окремо, а не перемикається глобально. Див. Посібник зі збірки » Отримання коду щодо команди клонування та того, як фіксується зміна всередині приватного пакета.
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Модель постачання платформи
Платформа працює на кількох поверхнях - веб-PWA, Tauri desktop/mobile, скриптований CLI та інтерактивний TUI. Усі вони використовують той самий двигун і ті самі файли інструментів.
Веб (PWA) - основне поширення
Розміщено за URL, контрольованим SUSE. Працює офлайн, щойно service worker кешував інструменти й активи. Тут більшість працівників, постачальників і партнерів користуватимуться платформою. Обліковий запис не потрібен - стан зберігається в IndexedDB на кожному пристрої.
Веб-оболонка адаптивна з одного макета. На комп'ютері інструмент - це бокова панель керування, яку можна змінювати розміром, поруч зі сценою попереднього перегляду з навігацією полотном, природною для трекпада (Cmd/Ctrl-колесо або щипок для масштабування навколо курсора, Space- або перетягування середньою кнопкою для панорамування, клавіші 0/1/+/− і HUD Fit/%). На мобільному (≤640px) керування стає аркушем, закріпленим зверху, з ручкою перетягування, що клацає в положення peek/half/full (дотик перемикає) над статичним повноекранним попереднім переглядом, а плаваюча кнопка Render відкриває керування Export у спливному аркуші знизу. Дотик отримує щипок-масштабування і перетягування-панорамування на попередньому перегляді. Шлях рендерингу і керування експортом ідентичні в обох випадках - переставляється лише хром.
signed by Lollyvector SVG131 paths~6.1k nodes158 groups1 image142 KBПеревірте саміОтримати підписаний файл
Той самий інструмент за ширини екрана телефону, без потреби підтримувати другий макет: елементи керування стають аркушем зверху, попередній перегляд займає весь екран, а плаваюча кнопка рендеру розміщена над ним.
signed by Lollyvector SVG97 paths~3.3k nodes113 groups99 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG97 paths~3.3k nodes113 groups100 KBПеревірте саміОтримати підписаний файл
Пакетний режим (/pro). Веб-оболонка також постачається з пакетною сіткою у стилі електронної таблиці (shells/web/src/pro/), яка рендерить багато рядків одночасно для одного або кількох інструментів. Вона підтримує обмін CSV/TSV, вставку з електронної таблиці, шаблон/формат/розмір/одиницю/dpi для кожного рядка, бічну панель редактора блоків із живим попереднім переглядом, згортані стовпці експорту, панель тегів "релевантності" для кожного рядка, перетягування рядків за лівий маркер, підтвердження видалення у два кроки, збережені пакетні сеанси та завантаження .zip. Це поверхня "один-до-багатьох" за позиціюванням "масове створення контенту".
Tauri для настільних і мобільних пристроїв
Пакетований нативний застосунок (невеликий обсяг завдяки Tauri). Забезпечує повну офлайн-доступність, доступ до файлової системи для інструментів, залежних від CLI (PDF Smasher, Font Outliner), і доступ до камери. Заплановано розширення інструментарію на середину 2026 року.
CLI
lolly <tool-id> [--input=value ...] --output=file.png
Користувачі настільних пристроїв можуть викликати багато інструментів із терміналу. Оболонка CLI завантажує той самий рушій, створює DOM через jsdom, виконує той самий шлях рендерингу і записує файл. Транспортом є режим 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 toolTUI
pnpm run tui
Інтерактивний аналог CLI: повноекранний, орієнтований на клавіатуру термінальний застосунок (побудований на Ink) для перегляду інструментів, заповнення полів уведення, збереження проєктів та експорту - усе без графічного інтерфейсу. Його міст хоста повторно використовує реалізацію CLI для форматів без DOM (SVG/EMF/EPS/HTML + текст/дані) і додає стан на диску в ~/.lolly та опційний вбудований попередній перегляд. Окрім цього, він має рівень рендерингу в браузері: обмежений headless-Chromium (той самий, який встановлює сервер MCP), що створює растр/PDF/відео та захоплення живих URL за запитом - керуючи зібраною копією веб-оболонки, тож результат ідентичний, і запускається лише тоді, коли ви вперше експортуєте такий формат. Тож url-shot (із обрізкою, перефарбуванням та векторним PDF/SVG) і кожен інструмент растру/pdf теж працюють у терміналі. Дивіться посібник з TUI.
Незалежно від того, якою поверхнею ви користуєтеся, вкладка Capabilities на панелі керування - це повна карта того, що платформа заявляє як свої можливості, згрупована й зрозуміла без відкриття жодного інструмента.
Категорії інструментів
Інструменти позначені category у своєму маніфесті для групування в галереї.
Рядки перелічені в порядку секцій галереї. Секція utility завжди рендериться останньою в галереї (після всіх інших категорій, включно з майбутніми) - це шухляда "Офлайн-утиліти" на пристрої.
| Категорія | Приклади | Заплановано |
|---|---|---|
everyone | QR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence, Record | Employee Image Stationery |
designer | Brand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, Booklet | Font Outliner |
event | Meeting Planner, Event Name Badge, Wayfinding Signage, Calendar ICS, Booth Studio | Event Stationery, Bulk Name Badges, Room Agenda Cards |
product | - | CVE Alert, Product Release Announcement, Blog OG Image |
utility | Strip Hidden Data, Text, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL Screenshot | Конвертери одиниць/форматів, більше локальних (on-device) утиліт приватності |
Ці клітинки - приклади, а не повний перелік. Які інструменти існують - це властивість змонтованого вами профілю, а не цієї сторінки: пакет бренду додає власні й може виключити інструмент спільноти, який не хоче постачати. catalog/tools/index.json - згенерований з маніфестів реєстр, який фактично читає галерея, - це авторитетний список; щоб порахувати, що монтує профіль, порахуйте маніфести (ls community//tool.json brands//tools/*/tool.json), а не покладайтеся на число, записане тут. (Ідентифікатор інструмента, наявний у двох пакетах, монтується один раз - із пакета-переможця.)
Інструменти також класифікуються за статусом: official (схвалено брендом, без водяного знака), community (зовнішній внесок), experimental (експорт із водяним знаком). Більшість бібліотеки має статус official; новіші студії та інструменти захоплення частіше мають статус community або experimental, поки не стабілізуються. Кожна поверхня показує значок, тож читач знає, що отримує, ще до відкриття - і, як і клітинки категорій вище, належність за статусом змінюється надто швидко, щоб перераховувати її тут. Дивіться це в галереї або в згенерованому індексі.
Design - перший інструмент, побудований на вільному режимі полотна render.layout: "editor" - безхромній поверхні прямого маніпулювання, де ви перетягуєте, змінюєте розмір, обертаєте та прив'язуєте блоки тексту, фігур і зображень, а потім експортуєте тим самим шляхом рендерингу, що й будь-який інший інструмент.
Strip Hidden Data - перший локальний (on-device) утилітарний інструмент (privacy: "on-device"): інструмент перетворення вмісту, який бере файл, наданий вами, повністю обробляє його в браузері і повертає чисту копію - вона ніколи не завантажується на сервер, ніколи не отримує водяний знак, у неї не вбудовується походження (provenance). Text - другий такий інструмент - локальна робоча панель для повсякденних задач типу "вставив на сайт" (форматування JSON, декодування JWT, Base64, кодування/декодування URL, хешування SHA). Compress PDF - третій - він зменшує розмір PDF, повторно стискаючи його зображення, також повністю на пристрої. Маркер і текст його значка "Працює на вашому пристрої - нічого не завантажується" тепер охоплюють увесь набір перетворень: Strip Hidden Data, Text, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (знищення ділянок зображення, SVG або PDF), Prompt Card і Rebrand (перебрендування .pptx на місці), там, де профіль його підключає. Це категорія утиліт приватності, яка замінює передачу конфіденційних файлів вузькоспеціалізованим вебсайтам.
signed by Lollyvector SVG124 paths~29k nodes324 groups395 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG124 paths~29k nodes324 groups396 KBПеревірте саміОтримати підписаний файл
Примітка:
categoryіstatusденормалізуються уcatalog/tools/index.json(реєстр, який читає галерея) з кожногоtool.json. Маніфест - джерело істини, а індекс генерується командоюpnpm run build:catalog, іpnpm run validate:catalogпровалює CI, якщо зафіксований індекс розходиться з маніфестами.
Архітектурні зобов'язання
Ці рішення остаточні. Зміна будь-якого з них - масштабне завдання - вони формують кожне інше рішення в кодовій базі.
1. Декларативні інструменти з імперативним запасним шляхом
Інструмент - це маніфест (tool.json) + шаблон (template.html) + опційний hooks.js.
Маніфест декларує вхідні дані. Не шаблон. Вхідні дані не виводяться з токенів Handlebars. Маніфест - контракт; шаблон споживає іменовані змінні через {{id}}.
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBПеревірте саміОтримати підписаний файл
Хуки опційні. Більшість інструментів є суто декларативними - маніфесту й шаблону достатньо. Інструменти, що потребують обчислюваних значень (кодування QR, формування даних діаграм), надають hooks.js, який експортує іменовані функції життєвого циклу (onInit, onInput, onFrame - хук живої камери для кожного кадру для реактивних до руху інструментів - onLevel, beforeExport, afterExport, exportFile - шлях перетворення файл-у/файл-з, що використовується утилітами на пристрої на кшталт Strip Hidden Data - та exportStill, для інструмента, що самостійно керує глибоким растром). Хост завантажує хуки через new Function('host', …) з мостом можливостей, інжектованим як область замикання. Це контракт переносимості, а не пісочниця безпеки: хуки досі виконуються в реалмі сторінки й можуть сягати window/fetch/document в оболонці браузера - host. є підтримуваною, переносимою поверхнею, а не примусовою межею. Асинхронні результати хуків обмежені за часом (onInit 5с, onInput 2с, beforeExport/afterExport 5с, exportFile/exportStill 10с), а запізнілі результати відкидаються; неконтрольований синхронний* хук неможливо витіснити. Тому виконання ненадійного стороннього коду хуків небезпечне, доки не з'явиться ізоляція через Worker.
Це важливо, тому що: декларативні інструменти можуть створювати люди без досвіду розробки. Якби кожен інструмент був окремим веб-застосунком, ризик "обмежені навички для створення/підтримки робочих шаблонів" перетворився б на постійне вузьке місце.
2. Інструменти й активи - це дані, а не вбудований код
Веб- і Tauri-застосунки отримують каталоги інструментів і активів з відомої URL-адреси під час запуску, кешують їх локально та працюють із тим, що там є. Додавання нової плитки для події чи сезонного активу не потребує релізу застосунку.
Байти активів контролюються сумою SHA-256 для запобігання отруєнню CDN. id активу + version керують інвалідацією кешу.
3. Міст можливостей - єдиний API, який бачать інструменти
Інструменти ніколи не торкаються DOM поза областю свого шаблону, ніколи не викликають fetch напряму, ніколи не читають файлову систему. Вони викликають версіоновані методи host.*. Канонічне визначення контракту - packages/core/src/host-v1.ts - SDK для авторів інструментів @lolly-tools/core, тож сторонній розробник може будувати на його основі, не залежачи від рушія; engine/src/bridge/host-v1.ts - це реекспорт типів із нього, і код рушія/оболонок продовжує імпортувати з цього шляху без змін:
| API моста | Що робить |
|---|---|
host.profile | Ім'я, електронна пошта, фото, місто користувача тощо. Попередньо заповнює поля через bindToProfile. |
host.assets | Запити до каталогу, розв'язання активів, наданий хостом інтерфейс вибору. |
host.state | Збереження / завантаження слотів уведення. IndexedDB у вебі, файлова система в Tauri, пам'ять у CLI. |
host.clipboard | Запис тексту або зображення в буфер обміну (із запасними варіантами для платформ). |
host.export | Растеризує або серіалізує ціль рендерингу. Застосовує водяний знак для експериментальних інструментів. |
host.net | Fetch зі списком дозволених адрес - доступний лише якщо інструмент задекларував можливість "network". (Наразі жоден інструмент у постачанні цим не користується.) |
Опційні, адитивні поверхні з'являються лише тоді, коли оболонка їх надає. Деякі з них обмежені можливостями - розкриваються лише коли інструмент декларує відповідний прапорець: 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) для хуків, що самі виконують піксельну роботу, connectors (1.106) для безпечних для експорту стрілок і c2pa (1.85) для підпису готових байтів. Кількість зростає; правила - ні.
Декларовані можливості: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, додано в 1.54, - це захоплення екрана через host.recorder - користувач обирає екран/вікно/вкладку в нативному інтерфейсі браузера; відрізняється від capture, яка растеризує URL, названу самим інструментом.)
Той самий інструмент працює в браузері, Tauri та headless CLI, тому що кожна оболонка реалізує цей інтерфейс - інструмент ніколи не знає, в якій з них він перебуває.
Міст версіонований. Додавання методів - мінорна версія. Видалення або зміна сигнатур - мажорне підвищення версії. Коли вийде v2, v1 має продовжувати працювати.
4. Ідентифікатори активів - назавжди
suse/logo/primary - це контракт. Після публікації:
- Ідентифікатор ніколи не змінюється, ніколи не використовується повторно.
- Зміна байтів → підвищення
versionу маніфесті. - Заміна новим активом → встановіть
deprecated: trueі опційноreplacedBy. - Наявні посилання завжди розв'язуються.
Це робить збережені стани інструментів і посилання, якими поділилися через URL, довговічними на роки.
5. Режим URL - першокласний
Кожне вхідне значення має бути виражуваним як параметр URL:
lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H signed by Lollyvector SVG55 paths~2.6k nodes38 groups60 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG55 paths~2.6k nodes38 groups61 KBПеревірте саміОтримати підписаний файл
Режим CLI - це режим URL під іншим транспортом - оболонка CLI будує об'єкт стану URL з argv і запускає той самий конвеєр рушія. Існує один шлях рендерингу. CLI не може розійтися з GUI, тому що не є окремою реалізацією.
url-mode.ts обробляє циклічне перетворення (розбір і серіалізацію). Набір зарезервованих параметрів ніколи не передається інструменту як вхідні дані: елементи керування виведенням (format, export, copy, filename, width/w, height/h, unit, dpi), перемикачі друку й походження (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) і носії стану (template, z - запакований токен "Найкоротше посилання" - і zx, те саме, зашифроване паролем). Набір RESERVED у engine/src/url-mode.ts є авторитетним джерелом і зафіксований тестом; URL Mode документує кожен із них, включно з тими кількома, що не перелічені тут. Вхідні дані активів у режимі URL серіалізуються за їхнім id; середовище виконання розв'язує їх через host.assets.get() перед гідратацією. width/height - це значення в unit (типово px, також mm/cm/in/pt/pc); з фізичною одиницею dpi задає роздільну здатність растру. Вони визначають розмір документа полотна й попередньо заповнюють панель розмірів експорту.
Оскільки кожне вхідне значення подорожує в посиланні, зміна параметра - це інший готовий актив. Уся ця палітра - це один початковий колір, гармонія та кількість кроків:
signed by Lollyvector SVG10 groups25 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG10 groups25 KBПеревірте саміОтримати підписаний файл
6. Збереження проходить через міст, а не напряму
Web-оболонка: 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). Синхронізація між пристроями вже працює поверх цього, надсилаючи той самий пакет до сховища, яке обирає користувач (docs/sync.md).
7. Мітки зрілості кажуть, чим є інструмент
Кожен інструмент оголошує status: official | community | experimental у своєму маніфесті. Галерея сортує за статусом. Експериментальні інструменти автоматично додають водяний знак на експортовані файли - водяний знак застосовує host.export.render, а не сам інструмент, тому автор інструмента, що не є офіційним, не може від нього відмовитися.
Це структурна відповідь на ризик сприйняття, за яким усі інструменти в галереї нібито мають однакову вагу. Будь-який процес, який команда вибудовує навколо каталогу, накладається зверху.
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- це повторювана група полів - міні-таблиця всередині одного поля, що редагується в бічній панелі, з типізованим/дискримінованим меню додавання та полями активів для кожного блока. Клацання на відрендереному блоці на полотні фокусує рядок цього блока. Використовується в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}}екранує 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) - без сервера, без адмін-консолі. Робота передається як сесія: посилання для спільного доступу несе її вхідні дані та налаштування (завантажені файли подорожують у
.lolly), і та сама сесія переноситься в резервній копії або через сесію співпраці. Той, хто контролює розгортання, може потім зафіксувати спільну сесію як шаблон - відкрити посилання, записати її значення як запис шаблону в каталозі цього інструмента в бренд-паку та закомітити - після чого він з'являється у виборі «New from template» цього інструмента і доступний за глибоким посиланням як?template=<id>. Git - це крок фіксації власника розгортання, а не автора. Для спільного, керованого каталогу організація може керувати каталогом активів так само і блокувати оновлення через рев'ю PR - це доступна модель врядування, а не вимога застосунку. - Немає примусового RBAC. Відкритий застосунок за замовчуванням публічно доступний; ризик для бренду керується тегами зрілості й водяними знаками. Організація, якій потрібен жорсткіший контроль, накладає власну автентифікацію та каталог з рев'ю в git, описаний вище.
- Немає центральної бази даних. Увесь стан користувача - на пристрої; опційна синхронізація копіює його до сховища, яке обирає користувач, і ніколи - до бази даних Lolly.
- Немає спільного шляху коду інструментів/рушія. Рушій - з відкритим кодом, так само як і бренд-незалежні інструменти в
community/; бренд-пак, як-от приватнийbrands/suse/, несе власні інструменти й каталог на власних умовах. У будь-якому разі поділ забезпечується примусово (немає перехресних імпортів зengine/у вміст інструментів), тож розділення лишається чистим.
Життєвий цикл одного рендеру
Користувач відкриває lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H:
- Завантаження (Boot). Веб-оболонка відкриває IndexedDB, створює міст можливостей (capability bridge), синхронізує каталоги інструментів і ресурсів (або завантажує їх з кешу в офлайн-режимі).
- Маршрутизація (Route). Хеш URL → відображення
tool, з яких видобуваютьсяqr-codeта параметри URL. - Завантаження (Load).
loadTool('qr-code', fetchFile)завантажуєtool.json, перевіряє його за JSON Schema, завантажує вихідний кодtemplate.html,styles.cssіhooks.js. - Розбір стану URL.
parseUrlStateперетворює параметри URL на початкові значення полів вводу. Посилання на ресурси (?logo=suse/logo/primary) розбираються як легкі об'єкти{ id, _unresolved: true }. - Середовище виконання (Runtime).
createRuntime(tool, host, initialValues)будує модель вводу (об'єднуючи дані профілю, значення за замовчуванням і початкові значення), розв'язує посилання на ресурси черезhost.assets.get(), завантажує хуки (hostу замиканні, без пісочниці), викликаєhooks.onInit. - Рендер (Render). Оболонка підписується на runtime; при кожній зміні стану вона отримує
{ model, hydrated }. Вона рендерить елементи керування вводом за моделлю і записує гідратований HTML шаблону в#tool-canvas. - Взаємодія (Interact). Користувач вводить текст у поле →
runtime.setInput(id, value)→ застосовуються обмеження → викликаєтьсяhooks.onInput→ повторна гідратація → повторний рендер. Полотно оновлюється в реальному часі. - Експорт (Export). Користувач натискає 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, рух (motion), редаговані документи (pptx,docx,odt), палітри та виводи даних/тексту, аудіо- та шрифтові файли. Режим URL перелічує кожен ідентифікатор і те, що він видає. Аудіо входить у цей перелік так само, як і все інше (wav,mp3,m4a,opus, що їх декларують audiogram та інструменти запису); окремо, режимrender.captureінструмента запису керуєhost.recorder, чий запис надходить як готовий Blob у тому контейнері, в якому браузер записав. (Інструменти, що встановлюютьrender.export: false- наприклад, Color Palette, Countdown Timer, Strip Hidden Data, Text, Compress PDF - приховують елементи керування завантаженням/форматом/розміром.) Фізичні одиниці тут конвертуються для кожного формату (PDF → справжні пункти сторінки, растр → пікселі за DPI з чанкомpHYs). Метадані авторства/походження (автор, інструмент, джерело - формуютьсяengine/src/metadata.ts) вбудовуються для кожного формату: PNG iTXt, JPEG EXIF, інформаційний словник PDF,<metadata>у SVG, коментар GIF. Для експериментальних інструментів водяний знак додає хост, а не сам інструмент.
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBПеревірте саміОтримати підписаний файл
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBПеревірте саміОтримати підписаний файл
Той самий життєвий цикл у Tauri. Той самий життєвий цикл у CLI - jsdom забезпечує безголовий DOM; вихід іде у файл або stdout.
Статус відкритого коду
Код ліцензовано за MPL-2.0. engine/, shells/, services/, schemas/ і docs/*.ts є відкритим кодом за ліцензією MPL-2.0 - платформа для брендованих інструментів, нейтральна щодо постачальника, уся вона в одному публічному репозиторії, lolly-tools/lolly.
Вміст інструментів постачається у вигляді брендових пакетів (brand packs), кожен зі своїми умовами (див. NOTICE.md пакета). community/ - це каталог цього репозиторію, і його бренд-незалежні інструменти теж під 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/. packages/node-shell/src/content-roots.ts відповідає на питання "де живе інструмент <id>" і "де каталог" на основі profiles.json під час читання, тож профіль - це відповідь для кожного процесу окремо, і жодне дерево не потрібно попередньо збирати. Справжня пара tools/ + catalog/ записується лише у вихідні файли збірки - dist/, пакет RPM, образ контейнера - оскільки браузер отримує ці два шляхи через HTTP.
Поділ забезпечується примусово — немає перехресних імпортів з engine/ у вміст інструментів — тож межа між платформою та вмістом лишається чистою.
Де закінчується двигун і починається хост
Якщо це можна описати чистими даними + Handlebars → двигун. Якщо це торкається DOM, файлової системи, мережі чи будь-якого API браузера/ОС → хост.
Ця межа гостра навмисно. Двигун - це частина з відкритим кодом. Усе, що знає про SUSE, конкретні платформи чи середовища виконання, залишається поза ним.
Для наступного рівня деталізації engine/README.md перелічує кожен модуль двигуна і за що він відповідає, а Модель загроз і межі довіри фіксує, де ця сама межа водночас є межею довіри.