يوثّق هذا المستند غرض منصة Lolly وبنيتها وقرارات هندستها المعمارية. وهو يعكس رؤية المنتج وحالة قاعدة الشيفرة الحالية في آن واحد.
الحالة: Lolly نموذج أولي داخلي في تجربة مغلقة لم تكتمل بعد. المحرك حتمي ومتّسق داخليًا، لكن المنتج لا يزال في مرحلة مبكرة - وSUSE هي العميل رقم واحد - ومحركاه الخاصان بالتشفير وتحليل الملفات يخضعان حاليًا لتصليب البنية التحتية الصارم الخاص بـSUSE، استعدادًا للنطاق المؤسسي (نحن بارعون جدًا في هذا). اقرأ البنية المعمارية أدناه على أنها نية تصميمية قيد الاختبار، لا منتجًا نهائيًا معتمدًا. راجع التبني والحوكمة لمعرفة كيفية إدارة التجربة وقياسها.
كيفية قراءة هذه الصفحة. تحمل هذه الصفحة نوعين من المحتوى، بالترتيب. النصف الأول هو سبب وجود هذا: المشكلة، والتموضع، ودورة حياة الأصل الواحد وهو يمر عبر المراحل. ومن الصورة الكبيرة فصاعدًا يصبح المحتوى كيفية تلاؤم الطبقات: مستند البنية المعمارية للمساهمين، ويغطي فصل المحرك/الغلاف/الحزمة، وتخطيط المستودع، وأهداف التسليم، والالتزامات التي تقيّد كل تغيير على المنصة. إذا كنت هنا لتغيير قاعدة الشيفرة لا لفهم المنتج، ابدأ من الصورة الكبيرة.
هناك مرجعان يتعمقان أكثر من هذه الصفحة.
engine/README.mdفي المستودع هو خريطة المحرك وحدة بوحدة، مع جدول مُولَّد لكل وحدة و ما تحلّله أو تكتبه. نموذج التهديد وحدود الثقة هو البنية المعمارية نفسها مقروءة كحدود ثقة، وهو الصفحة المناسبة لأي سؤال عن ما يعتبره المحرك غير موثوق.
سبب وجود هذا
تواجه الفرق مشكلة متكررة: عمل إبداعي ومحتوى متكرر يبلغ من القابلية للتنبؤ به حدًا لا يبرر تدخل أيدٍ ماهرة في كل مرة، لكنه في الوقت نفسه حساس للجودة بما يمنع تفويضه دون ضوابط. والنتيجة إما إنتاجية بطيئة (اختناق عند المتخصص)، أو عدم اتساق (كل شخص يستخدم أي أداة متاحة له)، أو ارتهان لمورّد (نظام إدارة أصول رقمية SaaS يتحكم في قوالبك).
هذه المنصة هي الإجابة المباشرة:
إبداع ومحتوى برمجي على نطاق واسع - توليد أصول بلا جهد بشري، مع بقاء القواعد تحت سيطرة مركزية، للموظفين والموردين والشركاء.
ليست Lolly المكان الذي يُبتكر فيه نظام تصميم - بل المكان الذي يُنتَج فيه. تخيلها كآلة بيع تصاميم: تختار، فتحصل على نتيجة. في كل مرة. يعمل المحرك على تحقيق أعلى جودة يمكن أن تنتجها كل صيغة على الجهاز أمامك، والمحرك نفسه يصنع الملف نفسه على كل سطح يُشحن إليه.
والنتيجة هي الوفرة: كل فعالية لها لافتاتها الصحيحة، وكل تنبيه CVE يطابق أسلوب الشركة، وكل ملصق يُطبع نظيفًا، وكل توقيع بريد إلكتروني محدَّث - كل ذلك دون تذكرة تصميم. تتولى المنصة العمل الإبداعي المتكرر المُشغَّل تشغيليًا. وهي بقصد ليست أداة تصميم مخصص - إذ يظل المصممون مالكي الأعمال الرائدة.
ابتكر احتماليًا، وانشر حتميًا
يتعثر كل نقاش حول الذكاء الاصطناعي في خط إنتاج إبداعي عند السؤال نفسه: أي جزء من هذا هو عمل الآلة؟ إنه سؤال قديم له إجابة راسخة. لطالما عمل النسّاخون ومزخرفو المخطوطات بين أداتين - المسودة الحرة، حيث لا شيء ثابت ويمكن تجربة كل شيء، والمطبعة، المخيفة تحديدًا لأنها كانت تلتزم بالنتيجة. المسودات كانت مكان حدوث الفن. والمطبعة كانت وسيلة وصوله إلى أي أحد. لم يخلط أحد بين الاثنين، وواصل كلاهما التقدم - أحبار جديدة، وخطوط جديدة، ومطابع جديدة - كل منها يتحسن بانسجام مع الحرفة والغاية التي يخدمها.
ترسم Lolly الخط نفسه. استكشف احتماليًا: نموذج، أو مصمم، أو فكرة أولية، أو موجّه (prompt) يذهب إلى مكان لم يخطط له أحد. ثم انشر حتميًا - فالشيء الذي يصل إلى عشرة آلاف مُخرَج هو أداة، والأداة تُنتج بالطريقة نفسها في كل مرة انطلاقًا من مدخلات يمكنك قراءتها. يبقى الاستكشاف حرًا لأن لا شيء لاحقًا يعتمد على وصوله إلى النتيجة نفسها مرتين. ويكتسب المُخرَج الثقة لأنه ليس تخمينًا. تحويل تجريب الذكاء الاصطناعي إلى نتائج يمكن التنبؤ بها وإعادة إنتاجها ليس تخصصًا جديدًا؛ إنه تقسيم العمل نفسه الذي جعل العمل المطبوع جديرًا بالثقة في المقام الأول.
ثِق بالعملية الإبداعية، وانشر بصرامة.
مقارنة بالبدائل
| 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 images2,269 KB
signed by Lollyvector SVGتحقق بنفسكGet the signed file281 paths~38k nodes443 groups6 images2,270 KB
استخدمها من أجل: التوليد السريع لأصول إبداعية مُشغَّلة تشغيليًا - بلاطات الفعاليات، وشارات الأسماء، والتوقيعات، وتنبيهات CVE، ورموز QR، والبطاقات الاجتماعية، وملصقات الشحنات، والتقارير المهيكلة.
لا تستخدمها من أجل: المحتوى الرئيسي المخصص.
دورة حياة حملة
أوضح طريقة لفهم ماهية Lolly ليست قائمة ميزات - بل تتبّع أصل واحد وهو ينتقل من يد إلى يد. راقب بطاقة حملة مُوطَّنة محليًا وهي تتحرك عبر المؤسسة:
- يضع المبدع القواعد. يؤلف مصمم القالب الأساسي في أداة التصميم، ويُدمج فيه متغيرات الطباعة والألوان الخاصة بالعلامة التجارية بشكل ثابت. هو لا يصنع بطاقة واحدة - بل يقوم بالعمل التأسيسي مرة واحدة حتى لا يضطر أبدًا إلى توطينها يدويًا مجددًا.
- ينشرها المطوّر على نطاق واسع. يُدمَج القالب نفسه في خط أنابيب ليلي عبر سطر الأوامر (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 جيدة للمصممين و جيدة للمطورين و جيدة للمبيعات، كل على حدة في فراغ. إنها سباق تتابع (relay race): يُنشر عمل المبدع الأولي على نطاق واسع بواسطة المطوّر، الذي يمكّن بدوره المُنتِج. التجربة السلسة للمندوب غير التقني في الطائرة ممكنة فقط بفضل الصرامة التي وضعها المصمم ونشرها المطوّر.
هذا هو مضاعِف القوة. Lolly ليست درجًا من أدوات منفصلة لأدوار منفصلة - بل هي دورة حياة حتمية واحدة للأصل يمسّها كل دور، وكل يد تمر بها تضاعف قيمة اليد التي سبقتها.
موافقة واحدة، عشرة آلاف أصل
بما أن الموافقة تعيش في الأداة لا في الملف (راجع كيف تقارَن Lolly)، يتوقف النطاق عن كونه مشكلة مراجعة. وافق على أداة بطاقة اجتماعية مُوطَّنة مرة واحدة، ثم ولّد 10,000 أصل عبر 12 لغة من جدول بيانات - ولا يحتاج أي منها إلى فحص امتثال جديد من الشؤون القانونية أو العلامة التجارية، لأن القالب الذي يأتي منه الجميع كان معتمدًا بالفعل.
تصل الأداة الحتمية نفسها إلى هذا النطاق بثلاث طرق، تنتج جميعها مخرجات متطابقة ومعتمدة مسبقًا:
- شخص، داخل التطبيق. شبكة الدُفعات
/pro: الصق الصفوف أو استوردها، واحصل على أصل واحد جاهز لكل صف، وحمّل ملف zip. دون مهارة تصميم، ودون تذكرة، ودون انتظار. - مطوّر، من سطر الأوامر. يشغّل سطر الأوامر (CLI) المحرك نفسه ومسار العرض نفسه بلا واجهة، بحيث يمكن تشغيل الأداة تسلسليًا على كل الصفوف العشرة آلاف في نص برمجي أو خط أنابيب ليلي. استدعاء
lolly <tool> --field=…داخل حلقة تكرار هو التكامل بأكمله. - نظام أو عميل ذكاء اصطناعي، عبر MCP. الأداة نفسها تُشغَّل برمجيًا، بالدقة نفسها وبنطاق أكبر حتى - لأن الآلة لن تملّ بينما تتدفق آلاف الملفات.
signed by Lollyvector SVGتحقق بنفسكGet the signed file348 paths~77k nodes537 groups7 images3,100 KB
signed by Lollyvector SVGتحقق بنفسكGet the signed file348 paths~77k nodes544 groups7 images3,103 KB
مجموعة واحدة من قيود العلامة التجارية، يثبّتها مصمم مرة واحدة؛ وثلاثة مسارات تؤدي إلى المخرج نفسه المعتمد مسبقًا - ويصل مسار الآلة إلى أبعد نطاق من الجميع، لأنها لا تتعب أبدًا بينما تتدفق الملفات.
الصورة الكبيرة: كيف تتلاءم الطبقات
كل ما يلي من هنا هو بنية معمارية. المخطط هو النظام بأكمله في نظرة واحدة: الأدوات هي بيانات في الأعلى، والمحرك في الوسط لا يعرف شيئًا عن أي منصة، والأغلفة (shells) أسفله تنفّذ عقدًا واحدًا، والكتالوجات توفّر المحتوى.
┌─────────────────────────────────────────────┐
│ 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 submodules) لهذا المستودع. يملك المستودع الأب engine/ وschemas/ وscripts/ وtests/ وapi/ وbrands/lolly-start/ و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
│
├── 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) - التوزيع الأساسي
مُستضاف على رابط تتحكم فيه SUSE. يعمل دون اتصال بمجرد أن يخزّن عامل الخدمة (service worker) الأدوات والأصول مؤقتًا. هنا سيستخدم معظم الموظفين والموردين والشركاء المنصة. لا حاجة إلى حساب - تُخزَّن الحالة في IndexedDB لكل جهاز.
غلاف الويب متجاوب من تخطيط واحد. على سطح المكتب، الأداة عبارة عن شريط جانبي لعناصر التحكم قابل لتغيير الحجم بجانب مسرح معاينة مع تنقّل أصلي في اللوحة عبر لوحة اللمس (عجلة Cmd/Ctrl أو القرص للتكبير حول المؤشر، والسحب بالمسافة أو بالزر الأوسط للتحريك، ومفاتيح 0/1/+/− ومؤشر Fit/% على الشاشة). على الجوال (≤640 بكسل)، تتحول عناصر التحكم إلى ورقة مثبَّتة أعلى الشاشة بمقبض سحب ينطبق على وضع اللمحة/النصف/الكامل (النقر يبدّل بينها) فوق معاينة ثابتة بملء الشاشة، ويفتح زر 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
الأداة نفسها بعرض الهاتف، دون تخطيط ثانٍ يجب الحفاظ عليه: تتحول عناصر التحكم إلى ورقة في الأعلى، وتشغل المعاينة الشاشة بأكملها، وتطفو حبة الرسم فوقها.
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
وضع الدفعات (/pro). يشحن غلاف الويب أيضًا شبكة دفعات بأسلوب جدول البيانات (shells/web/src/pro/) تُصيّر صفوفًا كثيرة دفعة واحدة عبر أداة واحدة أو عدة أدوات. تقوم بتبادل CSV/TSV ذهابًا وإيابًا بالإضافة إلى اللصق من جدول بيانات، وقالب/صيغة/حجم/وحدة/دقة لكل صف، ولوحة جانبية لمحرر الكتل مع معاينة حية، وأعمدة تصدير قابلة للطي، وشريط وسوم "الصلة" لكل صف، وإعادة ترتيب الصفوف بمقبض سحب على اليسار، وتأكيد حذف من خطوتين، وجلسات دفعات محفوظة، وتنزيل بصيغة .zip. هذه هي واجهة "واحد إلى كثير" وراء موضع "إنشاء المحتوى الجماعي".
تطبيق Tauri لسطح المكتب / الجوال
تطبيق أصلي معبأ (بصمة صغيرة عبر Tauri). يوفر إتاحة كاملة دون اتصال، ووصولًا إلى نظام الملفات للأدوات المعتمدة على CLI (PDF Smasher وFont Outliner)، ووصولًا إلى الكاميرا. مُجدوَل لتحسين الأدوات في منتصف 2026.
CLI
lolly <tool-id> [--input=value ...] --output=file.png
يمكن لمستخدمي سطح المكتب استدعاء أدوات كثيرة من الطرفية. يحمّل غلاف CLI المحرك نفسه، وينشئ DOM بواسطة jsdom، ويشغّل مسار التصيير نفسه، ويكتب الملف. وضع URL هو وسيلة النقل - CLI ليس تطبيقًا منفصلًا. هذا يضمن تطابق مخرجات CLI وواجهة المستخدم الرسومية.
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: تطبيق طرفية بملء الشاشة يعتمد أولًا على لوحة المفاتيح (مبني على Ink) لتصفح الأدوات، وملء المدخلات، وحفظ المشاريع، والتصدير - كل ذلك دون واجهة مستخدم رسومية. تُعيد جسرة المضيف الخاصة به استخدام تطبيق CLI لصيغ خالية من DOM (SVG/EMF/EPS/HTML + نص/بيانات)، وتضيف حالة على القرص ضمن ~/.lolly بالإضافة إلى معاينة مضمّنة اختيارية. وإلى جانب ذلك لديها طبقة تصيير بالمتصفح: كروميوم بلا واجهة رسومية ومحدود النطاق (نفسه الذي يثبّته خادم MCP) ينتج صورًا نقطية/PDF/فيديو والتقاطًا حيًا لعناوين URL عند الطلب - يشغّل نسخة مبنية من غلاف الويب بحيث تتطابق المخرجات، ولا يُطلق إلا عند أول تصدير لصيغة كهذه. لذا فإن url-shot (مع القص وإعادة التلوين وPDF/SVG المتجهي) وكل أداة raster/pdf تعمل في الطرفية أيضًا. راجع دليل TUI.
أيًا كانت الواجهة التي تستخدمها، فإن تبويب "القدرات" (Capabilities) في لوحة التحكم هو الخريطة الكاملة لما تُعلن المنصة أنها قادرة على فعله، مُجمّعة ومقروءة دون فتح أي أداة.
فئات الأدوات
تُوسم الأدوات بحقل category في بيانها للتجميع في المعرض.
تُدرج الصفوف بترتيب أقسام المعرض. يُعرض قسم utility دائمًا أخيرًا في المعرض (بعد كل فئة أخرى، بما في ذلك الفئات المستقبلية) - إنه درج "الأدوات المساعدة دون اتصال" العامل على الجهاز.
| الفئة | أمثلة | مخطط له |
|---|---|---|
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 | محوّلات الوحدات/الصيغ، والمزيد من أدوات الخصوصية العاملة على الجهاز |
هذه الخلايا أمثلة، لا قوائم جرد. الأدوات الموجودة فعليًا خاصية للملف الشخصي (profile) الذي ركّبته، لا لهذه الصفحة: تضيف حزمة العلامة التجارية أدواتها الخاصة، ويمكنها استبعاد أداة مجتمعية تفضّل عدم شحنها. 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 هي أول أداة مساعدة تعمل على الجهاز (privacy: "on-device"): أداة تحويل محتوى تأخذ ملفًا تُوفّره أنت، وتعالجه بالكامل في المتصفح وتُعيد نسخة نظيفة - لا تُرفع أبدًا، ولا تُوسم بعلامة مائية، ولا يُختم عليها أي مصدر (provenance). Text Helper هي الثانية - منضدة عمل تعمل على الجهاز لمهام اللصق اليومية في المواقع (تنسيق JSON، فك ترميز JWT، Base64، ترميز/فك ترميز URL، تجزئة SHA). Compress PDF هي الثالثة - تُصغّر ملف PDF بإعادة ضغط صوره، وذلك أيضًا بالكامل على الجهاز. تُغطّي العلامة ونص شارتها "يعمل على جهازك - لا شيء يُرفع" الآن مجموعة التحويل بأكملها: 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بشكل غير طبيعي (denormalised) إلىcatalog/tools/index.json(السجل الذي يقرؤه المعرض) من كلtool.json. البيان هو مصدر الحقيقة - الفهرس مُولَّد بواسطةnpm run build:catalog، ويفشلnpm run validate:catalogفي CI إذا انحرف الفهرس المُلتزم به عن البيانات.
الالتزامات المعمارية
هذه القرارات مستقرة. تغيير أي منها مهمة كبرى - فهي تُشكّل كل قرار آخر في قاعدة الشيفرة.
1. أدوات تعريفية (declarative)، مع مخرج طوارئ إجرائي (imperative)
الأداة هي بيان (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 - خطاف الكاميرا الحية لكل إطار للأدوات التفاعلية مع الحركة - وonLevel، وbeforeExport، وafterExport، وexportFile - مسار التحويل ملف-إلى-ملف الذي تستخدمه الأدوات المساعدة العاملة على الجهاز مثل Strip Hidden Data - وexportStill، للأداة التي تمتلك تصييرها النقطي العميق الخاص). يحمّل المضيف الخطاطيف عبر new Function('host', …) مع حقن جسرة القدرات كنطاق إغلاق (closure). هذا عقد قابلية نقل، لا صندوق حماية أمني: لا تزال الخطاطيف تعمل في نطاق الصفحة ويمكنها الوصول إلى window/fetch/document في غلاف متصفح - host. هو السطح المدعوم والقابل للنقل، لا حدًا مفروضًا. نتائج الخطاطيف غير المتزامنة محددة بمهلة زمنية (onInit 5 ثوانٍ، onInput ثانيتان، beforeExport/afterExport 5 ثوانٍ، exportFile/exportStill 10 ثوانٍ) وتُهمَل النتائج المتأخرة؛ ولا يمكن استباق خطاف متزامن* منفلت. لذا فإن تشغيل شيفرة خطافات من طرف ثالث غير موثوق ليس آمنًا إلى أن يصدر عزل Worker.
يهم هذا لأن: الأدوات التعريفية يمكن أن يُؤلّفها غير المطورين. لو كانت كل أداة تطبيق ويب، لأصبحت ملاحظة الخطر "مهارات محدودة لإنشاء/صيانة القوالب الأساسية" عنق زجاجة دائمًا.
2. الأدوات والأصول بيانات، لا شيفرة مُجمَّعة
يجلب تطبيقا الويب وTauri فهارس الأدوات والأصول من عنوان URL معروف عند الإقلاع، ويخزّنانها مؤقتًا محليًا، ويعملان بما هو موجود هناك. إضافة بلاطة فعالية جديدة أو أصل موسمي لا تتطلب إصدار تطبيق جديد.
بايتات الأصول محسوبة بمجموع اختباري SHA-256 لمنع تسميم CDN. id الأصل + version هما ما يُشغّل إبطال ذاكرة التخزين المؤقت.
3. جسرة القدرات هي الواجهة البرمجية الوحيدة التي تراها الأدوات
لا تلمس الأدوات أبدًا DOM خارج منطقة قالبها، ولا تستدعي fetch مباشرة أبدًا، ولا تقرأ نظام الملفات أبدًا. إنها تستدعي دوال host.* ذات إصدار. التعريف المرجعي للعقد هو packages/core/src/host-v1.ts - حزمة تطوير مؤلفي الأدوات @lolly-tools/core، بحيث يمكن لطرف ثالث البناء عليه دون الاعتماد على المحرك؛ وengine/src/bridge/host-v1.ts هو إعادة تصدير نوعي (type re-export) له، وتستمر شيفرة المحرك/الأغلفة في الاستيراد من ذلك المسار دون تغيير:
| واجهة الجسرة | ما تفعله |
|---|---|
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). البقية يُكتشف توفرها ميزة بميزة (feature-detected) - تكون حاضرة كلما استطاع الغلاف توفيرها، مع احتفاظ الأداة ببديل احتياطي للأغلفة التي لا تستطيع.
حفنة من الأسطح الرئيسية، لبيان ما تغطيه - يوثّق 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). خالصة ومتزامنة - تُلحق الأغلفة (shells) دالة المحرك makeColorApi() بدلاً من تنفيذ أي شيء بنفسها، فلا يمكن أن تنحرف عنها |
host.images | 1.60 | فك ترميز/تغيير حجم/إعادة ترميز البايتات على الجهاز - مسار التحويل (HEIC → JPEG، الضغط إلى WebP، تقليل الدقة). يُشحَن في غلاف الويب كواجهة كسولة (lazy facade)، بحيث لا يدخل مفكِّك ترميز HEIC أبدًا إلى حزمة الإقلاع |
host.geom | 1.64 | هندسة متجهية دقيقة: عمليات منطقية على المسارات، والإزاحة، وتحويل الخط إلى تعبئة، وتبسيط المنحنيات، والتبسيط، واختبار الإصابة (hit testing). خالصة ومتزامنة أيضًا وملحَقة من المحرك (makeGeomApi())؛ وتُعاد الإخفاقات كقيمة، لا تُرمى أبدًا |
البقية تتبع القواعد نفسها وموثّقة إلى جانبها: pdf (1.8) وpptx (1.58) لجراحة المستندات على الجهاز، وaudio (1.71) وspeech (1.96) لتحليل المقاطع والتحويل النصي/الكلامي على الجهاز، و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 و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 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 ويُشغّل خط أنابيب المحرك نفسه. هناك مسار تصيير واحد. لا يمكن أن ينحرف CLI عن واجهة المستخدم الرسومية لأنه ليس تطبيقًا منفصلًا.
يتولى 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 كل واحد منها، بما في ذلك الحفنة غير المدرجة هنا. تُسلسَل مدخلات الأصول في وضع URL بواسطة id الخاص بها؛ ويحلّها وقت التشغيل عبر host.assets.get() قبل الترطيب (hydration). 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 - فهي صغيرة جدا ولا يمكنها حمل البيانات الثنائية الكبيرة.
يمكن للمستخدمين حفظ عدة فتحات تحرير مسماة لكل أداة والعودة إلى كل جلسة لاحقا. لا حاجة لإنشاء حساب؛ الحالة خاصة بكل جهاز. ولأن الجسر هو المنفذ الوحيد، فإن هذه الحالة الخاصة بالجهاز قابلة للنقل أيضا: يقرأ 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هي مجموعة حقول متكررة - جدول مصغر داخل مدخل واحد، يُحرَّر في لوحة جانبية، مع قائمة إضافة مكتوبة/تمييزية وحقول أصول لكل كتلة. النقر على كتلة معروضة على اللوحة يركز على صف تلك الكتلة. تستخدمها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 اليوم. - رابط تضمين قابل للنقل -
<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). يستورد الأفراد ملفاتهم الإبداعية الخاصة مباشرة إلى فهرسهم داخل التطبيق (عرض الفهرس واستوديو العلامة التجارية) - بلا خادم، بلا لوحة تحكم إدارية. يُسلَّم العمل كـجلسة: يحمل رابط المشاركة الحالة كاملة، وتنتقل الجلسة نفسها في نسخة احتياطية أو عبر جلسة تعاون. يستطيع من يتحكم بالنشر بعدها تثبيت جلسة مشتركة كـقالب - يفتح الرابط، يسجّل قيمه كإدخال قالب في دليل تلك الأداة ضمن حزمة العلامة التجارية ثم يُثبّته (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، يبني جسر القدرات، يزامن كتالوجات الأدوات والأصول (أو يحمّل من ذاكرة التخزين المؤقت عند عدم الاتصال).
- التوجيه. تجزئة الرابط ← عرض
tool، مع استخراجqr-codeومعاملات الرابط. - التحميل.
loadTool('qr-code', fetchFile)يجلبtool.json، يتحقق منه مقابل JSON Schema، يجلبtemplate.htmlوstyles.cssومصدرhooks.js. - تحليل حالة الرابط.
parseUrlStateيترجم معاملات الرابط إلى قيم مدخلات أولية. مراجع الأصول (?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← إعادة الري ← إعادة العرض. اللوحة تتحدث حيا. - التصدير. ينقر المستخدم تنزيل (PNG) ←
runtime.export(canvasNode, 'png')←host.export.render(يرسم عبر dom-to-image-more؛ SVG/PDF تمر عبر مُتجهات مخصصة تمشي عبر DOM) ← كائن ثنائي ←host.export.download. نطاق الصيغ التي يمكن لأداة الاشتراك فيه واسع، وتعدادrender.formatsفيschemas/tool.schema.jsonهو المرجع بشأنه - نقاط نقطية وأخرى عائمة، متجهات وملفات قص، طباعة/CMYK، حركة، مستندات قابلة للتحرير (pptx،docx،odt)، لوحات ألوان ومخرجات بيانات/نصوص، ملفات صوت وخطوط. وضع الرابط يسمي كل معرف وما ينتجه. الصوت في ذلك التعداد كأي شيء آخر (wav،mp3،m4a،opus، معلن عنها من قبل مخطط الصوت وأدوات التسجيل)؛ بشكل منفصل، وضعrender.captureلأداة تسجيل يقودhost.recorder، الذي تصل لقطته ككائن ثنائي مكتمل في أي حاوية سجلها المتصفح. (الأدوات التي تضبطrender.export: false- مثل لوحة الألوان، مؤقت العد التنازلي، إزالة البيانات المخفية، مساعد النص، ضغط PDF - تخفي عناصر تحكم التنزيل/الصيغة/الأبعاد.) تُحوَّل الوحدات الفيزيائية لكل صيغة هنا (PDF ← نقاط صفحة حقيقية، نقطي ← بكسلات بدقة DPI مع كتلةpHYs). بيانات التأليف/المنشأ الوصفية (المؤلف، الأداة، المصدر - يبنيهاengine/src/metadata.ts) تُضمَّن لكل صيغة: PNG iTXt، JPEG EXIF، قاموس معلومات PDF،<metadata>في SVG، تعليق 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 - منصة سقالات محايدة تجاه المورّد لأدوات العلامة التجارية، مع كل وحدة قابلة للشحن في مستودعها الخاص تحت 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، نظام الملفات، الشبكة أو أي واجهة برمجة تطبيقات متصفح/نظام تشغيل ← المضيف.
الخط حاد عن قصد. المحرك هو الجزء مفتوح المصدر. كل ما يعرف عن SUSE، أو منصات محددة أو بيئات تشغيل يبقى خارجه.
لمزيد من التفاصيل، يعدد engine/README.md كل وحدة في المحرك ومسؤوليتها، ويسجل نموذج التهديد وحدود الثقة أين يتضاعف نفس الخط كحد ثقة.