mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-03 12:27:55 +08:00
main
44 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
54de349c47 |
fix: replace expired Discord invite (#4849)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local> |
||
|
|
1319bcef2e |
chore: prune curated official example plugins (#4815)
Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> |
||
|
|
29b138f7a3 |
feat(brands): turn any brand into a reusable design system (#4691)
* Implement brand management routes and CLI support - Added `brand-routes.ts` to handle HTTP endpoints for brand operations: listing, extracting, retrieving details, deleting, and serving logos. - Introduced `brands-cli-help.ts` for CLI commands related to brand management, including usage instructions for listing, creating, retrieving, and deleting brands. - Updated `cli.ts` to integrate brand commands into the existing CLI structure, allowing headless management of brands via the command line. - Created supporting files for brand metadata handling, including `design-md.ts` for rendering brand information in markdown format and `index.ts` for the brand engine API. - Implemented `prefetch.ts` to fetch and process brand material from specified URLs, ensuring a streamlined extraction process. - Enhanced server setup in `server.ts` to register brand routes and manage brand-related data effectively. This commit establishes a comprehensive framework for managing brands within the application, facilitating both HTTP and CLI interactions. * Enhance memory management and onboarding experience - Introduced canonical profile labels to ensure consistent handling of user input in profile forms, preventing duplicate entries. - Updated the `parseProfileBody` and `captureProfileFromForm` functions to utilize the new canonical label matching. - Added a memory callout section in the onboarding view to highlight the benefits of memory usage, including personalized responses and reduced setup questions. - Implemented new UI elements in the onboarding view to improve user engagement with memory features. - Expanded i18n support for new onboarding messages related to memory benefits across multiple languages. * Refactor onboarding flow and enhance design system integration - Updated the onboarding process to include a new brand extraction step, replacing the previous newsletter step. - Adjusted the tracking logic to reflect the new onboarding steps, ensuring accurate analytics for user progress. - Improved the UI for the onboarding view, including new input fields for email collection during the brand extraction phase. - Refined the EntryShell component to remove outdated comments and clarify the onboarding renderer's purpose. - Enhanced CSS styles for the onboarding steps to improve layout and user experience. - Updated internationalization strings across multiple languages to reflect changes in the onboarding flow and brand extraction messaging. * Add brand management features and enhance font handling - Introduced new modules for managing brand assets, including `chrome.ts` for headless Chrome operations and `fonts.ts` for self-hosting web fonts. - Implemented `prefetch.ts` to streamline the brand material extraction process, allowing for efficient harvesting of colors, fonts, and logos. - Enhanced the brand system with new schema definitions in `schema.ts` to support brand color and font management. - Developed the `engine` module to integrate brand building and rendering processes, including token derivation and artifact generation. - Improved the overall structure and organization of brand-related files for better maintainability and scalability. * Enhance brand extraction and project management features - Updated `brand-routes.ts` to include new dependencies for project management, allowing for the registration of brand-related projects. - Modified the `extractBrand` function to support project ID and system files, improving the brand extraction process. - Enhanced the CLI commands in `cli.ts` to handle project IDs during brand creation, enabling better tracking of brand projects. - Updated the server setup in `server.ts` to register new project-related routes. - Improved the UI components to display project information associated with brands, including buttons for opening projects in the `BrandDetailView` and `BrandsTab`. - Added new metadata fields in the contracts to support project tracking and management for brands. This commit establishes a more robust framework for managing brand projects, enhancing both backend and frontend functionalities. * Enhance onboarding profile management and memory persistence - Added new canonical profile labels for 'Organization size', 'Use cases', and 'Discovery source' to improve user input consistency. - Introduced `OnboardingProfileState` type to manage onboarding profile data more effectively. - Implemented functions to build and persist the onboarding profile body to memory, ensuring user selections are saved accurately. - Updated the `OnboardingView` component to handle profile persistence during navigation and submission steps. - Enhanced tests to verify that user selections are correctly persisted to the memory profile. This commit improves the onboarding experience by ensuring that user inputs are consistently captured and stored, enhancing overall user engagement with the application. * Reflow brand extraction into an agent-driven, live flow Replace the deterministic SSE prefetch/preview/system pipeline with an agent-driven extraction: POST /api/brands now reserves the brand and stands up a backing project with the target site open in an in-app browser tab plus a seeded prompt, so the agent measures, synthesizes brand.json incrementally, and the user can clear anti-bot walls by hand. New /preview and /finalize routes let the agent render the kit page live and register the resulting user:<id> design system, so extracted brand facts persist as a structured, reusable brand kit instead of a one-shot deterministic guess. Adds the brand-extract skill (SKILL.md + brand-kit.html template), kit-render engine, brand-extraction-engine tests, brand project covers in the Designs tab, onboarding extract handoff, and the matching od brand extract/preview/ finalize CLI subcommands and contract updates. Co-authored-by: Cursor <cursoragent@cursor.com> * Sediment finalized brands into structured memory Reflow a finalized brand into the memory store (brandToMemoryEntries + reflowBrandToMemory) so future chats can ground vague requests in the brand's palette, type, voice and rules. finalizeBrand now wires through the runtime dataDir and best-effort persists the brand, MemoryChangeEvent gains a 'brand' source, and the brand kit render hardens its inline JSON escaping. Adds brand.previewEmpty / brand.viewDetails across all locales. Co-authored-by: Cursor <cursoragent@cursor.com> * Implement logo fallback and imagery support in brand extraction - Introduced a deterministic logo fallback mechanism to ensure that brand extraction processes can retrieve and save site logos, even when the agent fails to do so. - Enhanced the `startBrandExtraction` and `finalizeBrand` functions to utilize the new logo fallback, allowing for better handling of logo assets. - Added support for imagery samples in brand validation, enabling the inclusion of representative images in the brand kit. - Updated the brand kit rendering to include self-hosted fonts and imagery, improving the overall presentation of brand assets. This commit strengthens the brand extraction workflow by ensuring that logos and imagery are reliably captured and displayed, enhancing the user experience in brand management. * Enhance memory management with rule proposal and verification features - Introduced new functionality for distilling annotations into rule proposals, allowing users to suggest rules based on in-canvas annotations through the `od memory rule suggest` command. - Implemented a verification system that programmatically enforces compliance with active rules during artifact generation, ensuring that all active rules are covered in the self-verify scorecard. - Added endpoints for managing verification outcomes, including listing, removing, and clearing verification records, enhancing the transparency of the verification process. - Updated the memory management system to support the retrieval of active rule entries, ensuring that only linked rules are considered during verification. - Enhanced tests for both rule proposal generation and verification processes to ensure reliability and correctness. This commit strengthens the memory management capabilities by integrating rule proposals and verification, improving the overall user experience in managing design rules and ensuring compliance. * Distill review annotations into memory and enforce self-verify scorecard Add distillAnnotationsToMemory to mine inline preview comments/highlights/ marks into durable feedback + rule memory via a dedicated distiller prompt, threaded through the existing extract pipeline with an 'annotation' change source. Tighten the self-verify prompt (daemon + contracts) to state the daemon programmatically checks the scorecard, so a missing or uncovered scorecard on an artifact turn is an enforcement failure. Cover the rule suggest and verification-history routes with tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Apply brand design system through web config on "Use in new chat" Thread onApplyDesignSystem from the entry shell into BrandsTab so the brand's registered design system is applied via the web config channel instead of a bare daemon PATCH that left the Home composer stale. Add a transient home-intent latch + event so the Brands tab can request the Prototype chip on the already-mounted HomeView, which consumes it once the plugin catalog loads. Co-authored-by: Cursor <cursoragent@cursor.com> * Wire annotation distillation into background memory extraction Add a background distill pass that mines inline review annotations (comments / highlights / drawn marks) from a turn into durable memory alongside the general LLM extraction, surface an `annotation` memory toast source in the web UI, and cover the flow with a unit test. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix brand design system not applying to composer on "Use in new chat" Selecting a brand's "Use in new chat" applies the brand's design system as the default and fires the Prototype chip intent in the same synchronous click handler. HomeView consumed that intent inside the event listener, so `pickChip` ran before React committed the config change and seeded the composer's design-system field from the stale (empty) default — the composer showed "No design system" instead of the brand until a reload. Split the intent handling: the listener now only bumps a tick, and a separate effect consumes the chip after the re-render lands, so the seeded design system reflects the freshly-applied brand. Add the previously-untracked home-intent latch test coverage. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(web): rework Brands into Brand Kit and add Home create entry Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): harvest real cover/hero images for the Images module The brand kit's Images gallery only populated when the extraction agent remembered to save imagery — so a forgetful or bot-blocked agent (and the pre-imagery "Open Design" brand) left it empty. Add a deterministic, server-side imagery fallback (imagery-fallback.ts), mirroring the logo fallback: it parses og:image/twitter:image, large <img> (highest-res srcset/<picture>), <link rel=preload as=image>, and CSS background-image hero blocks, fetches candidates with browser-shaped headers, decodes PNG/GIF/JPEG/WebP dimensions to keep only big representative images (dropping icons/sprites/logos/tracking pixels), dedupes by content hash, and saves up to 8 of the largest into imagery/ with labeled samples. finalizeBrand runs it as a timeout-bounded, failure-tolerant safety net (injectable so tests stay offline) when the agent captured too few samples, first adopting any on-disk images. The extraction prompt and brand-extract SKILL now explicitly direct the agent to harvest the site's large/cover/hero images, filtered by rendered size. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(qa): implement deck layout validation and safety checks Add a new QA module for validating the layout of generated brand decks to ensure robustness against clipping and truncation issues. The `analyseDeckLayout` function checks for critical layout invariants, including the presence of `.slide` sections, correct container types, and necessary runtime layers. Introduce `assertDeckLayoutSafe` to enforce these checks during brand system rebuilds, preventing the deployment of decks that fail validation. Additionally, create comprehensive tests to verify the functionality of the new layout validation features. * fix(brands): apply deck shrink-to-fit synchronously so slides never clip The no-clip runtime scheduled its fit pass through requestAnimationFrame, whose callbacks are throttled while the deck is offscreen or occluded. A slide could therefore stay unscaled — and clip its content — until first paint. Fit synchronously on resize/load/fonts-ready with a trailing setTimeout settle pass for late reflow, removing the rAF dependency. Verified at the previously-broken 1024x620 viewport: container-type:size, zero truncations, runtime auto-applies scale (Problem 0.71, ASK 0.87, Product 0.97, Competition 0.97) and frame clip count drops to 0. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(web): let New Brand modal embed scrollable brand reference picker Add a fillHeight mode to BrandReferencePicker so the heading, quick-pick row and controls stay pinned while only the gallery scrolls inside a bounded-height parent. Wire it into NewBrandModal with a stable, spacious dialog and refresh the related newBrand/brandPicker copy across all 18 locales. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): enhance brand extraction with deterministic seed harvesting Introduce a new `seed-fallback` module to provide a server-side deterministic palette and typography seed during brand extraction. This ensures that the brand kit's initial display includes a harvested logo, an approximate color palette, and font families, improving the user experience by reducing the all-skeleton appearance during the first paint. Update the `startBrandExtraction` function to utilize this new module, allowing for a more seamless and visually appealing brand extraction process. Additionally, enhance the `BrandReferencePicker` component to reflect loading states and errors during brand extraction, ensuring users receive immediate feedback on their actions. Update related tests to verify the idempotency of the `finalizeBrand` function, ensuring that re-finalizing a brand correctly reuses the existing design system without duplication. * feat(brand-extract): enhance BrandReferencePicker and localization updates Updated the BrandReferencePicker component to reflect loading states and errors during brand extraction, improving user feedback. Added a new localization key for the brand extraction process and updated existing translations in English, Simplified Chinese, and Traditional Chinese to enhance clarity and user experience. Additionally, introduced new styles for better interaction with brand assets in the brand kit template. * feat(brands): wire in-page lightbox/masonry/asset preview + refine seed Brand-kit preview improvements for the live extraction kit: - brand-kit.html: add in-page overlay system (sandboxed iframe has no top-nav) — clickable image lightbox with prev/next, a "view all" masonry modal, and a full-page asset preview modal that loads system/artifacts/<kind>.html in an iframe. Defer auto-reload while an overlay is open so it never yanks the modal out mid-interaction. - seed-fallback.ts: prefer vivid mid-luminance hues for the seeded accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.) from the typography seed so specimens never render glyph soup. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): wire in-page lightbox/masonry/asset preview + refine seed Brand-kit preview improvements for the live extraction kit: - brand-kit.html: add in-page overlay system (sandboxed iframe has no top-nav) — clickable image lightbox with prev/next, a "view all" masonry modal, and a full-page asset preview modal that loads system/artifacts/<kind>.html in an iframe. Defer auto-reload while an overlay is open so it never yanks the modal out mid-interaction. - seed-fallback.ts: prefer vivid mid-luminance hues for the seeded accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.) from the typography seed so specimens never render glyph soup. Co-authored-by: Cursor <cursoragent@cursor.com> * i18n(web): add brandPicker.opening across remaining locales + picker test Completes the brand-reference picker i18n key that was committed only for en/zh-CN/zh-TW, so every locale satisfies the typed Dict, and lands the BrandReferencePicker extraction-feedback test left untracked by the concurrent worker. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(EntryShell): enhance AMR cloud card visibility post-detection Updated the EntryShell component to ensure the AMR cloud card remains visible after detection settles, even when the AMR runtime is unavailable. This change prevents the card from disappearing and allows it to degrade gracefully to fallback content and sign-in flow. Additionally, added tests to verify the new behavior, ensuring a better user experience during onboarding. * feat(library): OD Library asset registry + OD Clipper extension Add a global, cross-project asset registry (OD Library) and a Chrome MV3 capture extension (OD Clipper), wiring the full HTTP + CLI + Web UI three-track loop per specs/od-clipper.md. - contracts: LibraryAsset/Source/Kind, ingest, search, pairing, task DTOs - daemon: 6 additive SQLite tables, content-addressed owned storage, the idempotent registerLibraryAsset hook (hash dedup + append-source), programmatic enrichment (mime/size/image dims/domain/tags), pairing tokens with a persisted extension-origin allowlist, /api/library/* routes, and /api/tools/library/{search,apply} for in-task agent reuse - cli: `od library list|get|rm|search|import|pair` - web: Library tab (grid, source badges, filters, search, live SSE updates, extension pairing affordance) - clipper/: standalone MV3 extension (background SW, content toolbar, popup) - skills/library-curator: utility skill for agent-driven asset reuse Origin middleware now honors paired chrome-extension:// origins (seeded from SQLite on boot) and exempts the pairing-confirm handshake. Enrichment AI stages (caption/OCR/embedding) are recorded as skipped pending a configured model. * feat(brands): programmatic-first design system extraction + rename Make brand extraction two-phase so a usable design system is ready the moment the user enters a URL — the instant "aha" — instead of waiting on the AI agent: 1. PROGRAMMATIC-FIRST (synchronous): startBrandExtraction now harvests the site deterministically (logo, palette, typography, one-line description, cover imagery, source URL) via prefetchBrand, synthesizes a valid design system with brandFromMaterial (no LLM), and finalizes + registers it before returning. finalizeBrand is refactored into a reusable finalizeBrandCore shared by both the programmatic path and the agent path. 2. ASYNC AI ENRICHMENT: the seeded agent prompt is reframed to enrich the already-usable design system and re-finalize in place (same user:<id>), updating every artifact/template. Bounded + best-effort: a blocked/unreachable origin skips phase 1 and stays `extracting` for the agent to drive. Gated on userDesignSystemsRoot so the legacy agent-only path stays intact for tests. Also rename the user-facing "Brand Kit" surface to "Design System" across en + zh-CN strings, project names, and the enrichment prompt. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(library): enhance asset import and management features - Updated the `import` command to allow multiple local files and remote URLs, with restrictions on supported formats. - Added new commands: `apply` for copying assets into project design files, `edit-as-page` for converting HTML assets into editable projects, and `figma` for exporting Figma captures. - Introduced sidecar functionality for storing derived data alongside owned assets, including Figma capture IR and element HTML. - Enhanced server configuration to support larger ingest payloads for asset captures. - Improved error handling and user feedback during asset import and application processes. * feat(asset-management): enhance asset dropzone and introduce chat-to-design feature - Updated the DesignSystemAssetDropzone component to improve file preview handling with new functions for creating and revoking object URLs. - Adjusted CSS for better layout and spacing in the asset dropzone. - Added a new "Chat to design" button in the LibrarySection component, allowing users to send selected assets to the Home chat composer for project creation. - Updated localization strings across multiple languages to reflect changes in asset import terminology. - Enhanced the HomeView component to handle asset staging from the chat composer. * feat(library): enhance asset application with element markup support - Updated the `applyLibraryAsset` function to include an `includeElement` option, allowing the capture of element markup alongside assets. - Modified related components (e.g., `ChatComposer`, `LibrarySection`, `FileWorkspace`) to handle the new element markup feature, ensuring both asset paths and optional element paths are returned and processed. - Introduced a new function, `fetchLibraryAssetElementHtml`, to retrieve the captured HTML for element-pick assets. - Enhanced the UI to display element markup inline within the chat composer, improving user interaction with captured elements. - Updated API contracts to reflect changes in asset application responses, including optional element markup paths. * feat(library): enhance asset filtering and preview handling - Updated the LibraryPicker and LibrarySection components to implement a badge-aware kind filter, allowing for more precise asset filtering based on badge kind. - Introduced a new `matchesKindFilter` function to streamline the filtering logic across components. - Enhanced the DesignSystemAssetDropzone to ensure proper handling of image previews, addressing issues with broken thumbnails under React StrictMode. - Added CSS styles for kind badges to improve asset representation in the UI. - Implemented tests for the DesignSystemAssetDropzone to ensure correct preview lifecycle management. * feat(library): hydrate single asset on SSE ingest Add fetchLibraryAsset(id) so the Library grid can merge just the one asset an `ingest` SSE event references instead of refetching the whole list on every capture. Returns null on miss/error. * feat(clipper): richer in-page image picker Collect CSS background-image url()s in addition to <img> (so hero/section art painted as backgrounds is no longer silently missed), defer thumbnail decode to visible cells via IntersectionObserver, draw downscaled canvas thumbnails instead of second full-res decodes, and add locate-on-page highlighting so a picked image can be traced back to its DOM source. * feat(library): implement lazy loading for thumbnails and enhance asset filtering - Introduced a `LibraryThumb` component to lazily load heavy content (images, videos, iframes) only when they are near the viewport, improving performance. - Added a debounced search feature to optimize asset filtering, reducing unnecessary network requests during rapid input. - Enhanced the asset filtering logic to track active filters using a ref, ensuring efficient updates during live events. - Updated the `snapshotCardRects` and `cardIdsInBand` functions to support improved hit-testing for drag-and-drop interactions. * feat(library): lazy picker thumbnails + debounced search Extend the Library grid's lazy-thumbnail + 250ms debounced-search pattern to the composer LibraryPicker so opening it no longer fires one full-bytes request per asset, and tidy the clipper content-script image collection. * feat(clipper): compress and budget capture inlining Re-encode large raster images to downscaled WebP and inline smallest-first within a fixed budget, dropping only the secondary Figma IR past a safe body size, so an image-heavy page (e.g. a news front page) always saves as an editable HTML capture instead of 413-failing the ingest. * test(library): LibraryPicker debounce + lazy-thumbnail coverage Cover the composer picker's 250ms debounced search and its lazy <img> mount (deferred until the card is in view), matching the grid's perf test. * feat(design-system): enhance asset handling and UI for design systems - Updated the CLI to support additional asset kinds, including 'design-system'. - Enhanced the DesignSystemProvenance type to include source URLs, improving provenance tracking. - Modified the design system generation jobs to correctly summarize source links and GitHub repositories. - Updated UI components to reflect changes in asset handling, including new source link management in the DesignSystemFlow. - Improved tests to cover new functionality for adding source links and ensuring proper handling of design system assets. * refactor(library): rename 'design-system' to 'brand kit' and enhance thumbnail loading - Updated labels and filters in Library components to replace 'design-system' with 'brand kit'. - Introduced a shimmer skeleton for lazy-loaded thumbnails in the LibraryPicker to improve user experience during asset loading. - Enhanced the PickerCard component for better performance by memoizing individual asset cards. - Updated tests to ensure proper handling of brand kit assets and their visibility in the LibraryPicker. * feat(clipper): implement internationalization for toolbar and popup - Added i18n support to the clipper, enabling localization of UI elements and tooltips. - Introduced a new i18n.js file to manage translations for various languages. - Updated content.js and popup.js to utilize the i18n functions for dynamic text rendering. - Enhanced accessibility by ensuring aria-labels and tooltips are also localized. - Improved user experience by providing localized messages for actions and statuses. * feat(clipper): enhance brand kit extraction and localization support - Updated the brand kit extraction process to include improved handling of assets and localization for various UI elements. - Added internationalization support for the brand kit feature, allowing for dynamic text rendering based on user locale. - Enhanced the user experience by ensuring that all relevant messages and tooltips are localized. - Updated tests to cover new localization features and ensure proper functionality of the brand kit extraction process. * feat(clipper): enhance brand color derivation and update localization - Introduced new functions for color manipulation, including linear interpolation and clamping, to improve brand color derivation. - Updated the deriveBrandColors function to better map observed palettes to semantic roles, ensuring consistent brand representation. - Revised localization strings in i18n.js to reflect changes from 'brand kit' to 'design system', enhancing clarity and user experience. - Improved overall code organization and readability by refactoring existing functions and adding new utility methods. * refactor(clipper): update terminology from 'brand kit' to 'design system' - Replaced all instances of 'brand kit' with 'design system' across various components and localization files for consistency. - Updated UI elements, tooltips, and documentation to reflect the new terminology. - Enhanced user experience by ensuring clarity in the design system extraction process and related functionalities. - Adjusted localization strings in multiple languages to align with the updated terminology. * feat(clipper): enhance image fill handling and normalization - Introduced functions to normalize image fills by converting non-PNG/JPEG formats (SVG, WebP, GIF, AVIF) to PNG before import, ensuring all images are properly rendered in Figma. - Updated the UI to report the number of images converted and dropped during the import process, improving user feedback. - Enhanced the overall image processing workflow to prevent silent failures when unsupported formats are encountered. - Revised documentation to reflect the new image handling capabilities and supported formats. * feat(clipper): enhance UI kit and busy state feedback - Updated the UI kit to include new components such as inputs, selection, and overlays, improving the overall design system representation. - Enhanced the busy state feedback during capture processes with localized messages and a step-by-step progress indicator, providing users with clearer status updates. - Revised localization strings to support new UI elements and improve user experience across multiple languages. - Improved documentation to reflect changes in the UI kit and busy state handling. * fix(brands): restore design-systems nav entry + reconcile BrandsTab on re-activation Address review feedback on PR #4260: 1. EntryNavRail dropped the only control that reached view==='design-systems' when Brands replaced it in the rail, leaving the still-rendered/routed design-system manager deep-link only (the entry-nav-design-systems e2e specs assert this). Restore a reachable rail entry (blocks icon, existing navDesignSystems key) alongside Brands. 2. BrandsTab only fetched once on mount, but EntryShell keeps sub-views mounted and toggles visibility, so a brand finishing extraction in its backing project never reconciled until a full reload. Refresh whenever the Brands view becomes active again, and poll while any brand is extracting (torn down once settled / when hidden). Red spec: tests/components/BrandsTab.refresh.test.tsx (fails pre-fix: fetchBrands called once, not twice). * Update clipper/brand-capture.js * fix(clipper): improve busy state handling and UI feedback - Adjusted the spinner CSS to use flex properties for better layout control. - Enhanced the reclampIfMoved function to preserve user position during busy state transitions. - Added loading toast notifications for popup-launched captures to ensure progress visibility even when the on-page bar is hidden. * feat(daemon): add kiwi-schema dependency and enhance Figma API integration - Added kiwi-schema package to the daemon for improved schema handling. - Updated FigmaApiNode interface and related functions to support shared functionality with the offline decoder, ensuring consistency in node processing. - Refactored capture functions in clipper to maintain UI visibility during DOM/IR snapshots, enhancing user experience during capture operations. * fix(web): surface missing backing projects * fix(web): re-enable brand actions after use * fix(daemon): serve brand logos from data roots * fix(brands): reconcile failed extractions * feat(daemon): implement offline Figma import and decoding functionality - Added support for importing `.fig` files directly into the daemon, enabling offline processing without requiring a Figma account. - Introduced a new `fig-decode.ts` module for decoding `.fig` files, handling both ZIP-wrapped and raw formats. - Created `figma-import.ts` to orchestrate the import process, generating a canonical snapshot and associated metadata. - Enhanced the server to handle Figma file uploads and integrate with the new decoding logic. - Updated package dependencies to include `kiwi-schema`, `html2canvas`, and `jspdf` for improved functionality. - Added tests for the new Figma import features to ensure reliability and correctness. * feat(clipper): reload-proof capture progress badge on the extension icon The on-page progress strip dies if a page reloads itself mid-capture (aggressive paywall sites like economist.com do this), leaving no loading signal. Add a per-tab '•••' badge on the extension icon for the lifetime of any capture message — it lives on the action icon, so a page navigation can't take it down. Verified end-to-end via a real loaded extension. * feat(daemon): add export functionality for Figma and enhance PDF export process - Introduced `runFigma` command for importing Figma designs, supporting both local `.fig` files and Figma URLs. - Added detailed usage instructions for the `od figma import` command. - Implemented `runExport` command for programmatic export of HTML/deck artifacts to PDF, PPTX, or image formats. - Enhanced error handling and user feedback during export processes. - Removed obsolete `build-pptx-export-prompt` module and related tests to streamline the codebase. * feat(daemon): enhance library synchronization and export capabilities - Implemented `reconcileLibrary` to mirror design systems and agent-produced project deliverables into the Library as referenced assets. - Added support for programmatic export of artifacts via the `od export` command, including detailed usage instructions. - Introduced new functions for handling Figma imports and exports, improving integration with design workflows. - Enhanced error handling and user feedback during synchronization and export processes. - Added tests for new features to ensure reliability and correctness. * feat(web): PPTX export for any shareable artifact + Library toolbar tooltips * chore(nix): refresh pnpm deps hash * refactor(web): enhance onboarding view and file export progress indicators - Updated the onboarding view layout for improved accessibility and visual hierarchy, including adjustments to spacing, typography, and button styles. - Introduced a loading toast for file export progress, displaying elapsed time and estimated time remaining for slide exports. - Added new translation keys for export progress messages in multiple languages. - Refactored the export progress handling to provide real-time updates during the export process, improving user feedback and experience. * refactor(web): streamline export capture bridge and update connector styles - Removed unused loading logic for html2canvas in the export capture bridge, simplifying the code. - Updated CSS for the onboarding view connector to improve visual clarity and ensure it does not overlap with node numbers. * refactor(web): remove html2canvas dependency and enhance Figma URL handling - Removed the html2canvas package from the project, including its references in the lock file and related components. - Added functionality to manage Figma URLs within the Design System flow, allowing users to add, remove, and validate Figma file links. - Improved drag-and-drop handling to prevent unintended file navigation when dropping files outside designated areas. - Updated UI components to accommodate new Figma URL features, enhancing user experience and accessibility. * refactor(web): unify brand and design system flows - Merged the brand extraction process into the design system creation workflow, allowing users to start from a brand directly within the design system wizard. - Updated routing to redirect legacy brand links to the unified design systems tab. - Enhanced the onboarding experience by removing the separate Brand Kit tab and integrating brand selection into the design system creation process. - Improved UI components to reflect these changes, ensuring a seamless user experience across the application. * feat(web): introduce brand enrichment banner and picker modal - Added a new BrandEnrichmentBanner component to allow users to refine programmatically-extracted design systems with AI by selecting design-system skills. - Implemented a BrandPickerModal for selecting brands from a searchable gallery, enhancing the design system creation flow. - Updated ChatPane to conditionally display the enrichment banner for eligible brand projects, improving user engagement. - Enhanced the design system flow to support the new brand enrichment features, ensuring a seamless experience for users. * feat(web): enhance BrandPickerModal and DesignSystemAssetDropzone - Updated the BrandPickerModal to allow scrolling of the entire picker area, improving user experience by creating a unified scrolling surface. - Added new props to the BrandReferencePicker for action labels and scroll root reference, enhancing flexibility in brand selection. - Introduced a new DesignKitView component for rendering design kits consistently across different surfaces. - Enhanced the DesignSystemAssetDropzone to support a wider variety of file types with appropriate previews, improving asset management during design system creation. - Updated styles for better visual clarity and responsiveness across components. * feat(web): update Design Systems tab actions and enhance localization - Changed the button label in the DesignSystemsTab from "Edit" to "Open" for better clarity in user actions. - Added a new translation key for 'dsManager.openSystem' across multiple languages to support the updated button label. - Enhanced the FileWorkspace component to ensure the Design Files tab aligns correctly with the Design System tab, improving UI consistency. - Implemented a new design system editing feature that allows users to fetch and save design system content from DESIGN.md, enhancing the design workflow. * fix(merge): repair post-merge regressions after origin/main integration Follow-up fixes on top of the origin/main merge ( |
||
|
|
0bf1b6d6b8 |
[codex] converge release workflows and stable dry-runs (#4390)
* fix(tools-pack): use junctions for Windows standalone peer deps * fix(desktop): expose IPC during startup * fix(tools-pack): preserve Windows inspect diagnostics * fix(tools-pack): report Windows inspect status errors * fix(packaged): use Electron net fetch for app protocol * fix(packaged): load Windows renderer from web sidecar * fix(desktop): show Windows packaged window during startup * fix(packaged): disable Windows GPU startup * fix(tools-pack): keep Windows core smoke observable * fix(packaged): remove Windows startup probes * fix(tools-pack): trace Windows desktop IPC status * fix(tools-pack): add Windows IPC diagnose loop * fix(release): default beta-s Windows updater feed * chore: clean merged test eof * refactor(release): unify prerelease channel model * chore(release): close prerelease doc escape hatches * refactor(release): converge release channel workflows * fix(release): install toolchain in metadata jobs * fix(release): build release package before contracts * chore(release): bump development version to 0.10.1 * fix(e2e): seed windows packaged smoke runtime config * fix(release): install toolchain for metadata publish * fix(release): materialize betas metadata checkout * chore(release): bump development version to 0.10.2 * fix(release): allow betas metadata cold start from s3 * fix(e2e): support betas packaged update scenarios * fix(release): pass betas channel into packaged smoke * fix(release): set betas channel during self-hosted builds * fix(release): verify counted channel reservations * fix(release): use pnpm cmd for betas windows publish * fix(release): add betas manifest artifact fallback * fix(release): skip beta-s public metadata fetch * fix(release): read beta-s manifests from storage * fix(release): cache beta windows tools-pack builds * fix(release): inline beta mac tools-pack builds * fix(pack): deep sign unsigned mac bundles * docs(pack): document payload-first beta updater validation * fix(release): align preview tools-pack cache flow * fix(release): align prerelease tools-pack cache flow * fix(release): pass github token to prerelease metadata * fix(release): setup pnpm before feishu notify * fix(release): add stable dry-run prepublish flow * fix(release): accept completed prerelease metadata gate * fix(release): require stable release branches * fix(release): converge r2 access checks * fix(updater): use release channel parser for defaults * fix(updater): harden windows payload relaunch * fix(release): converge updater smoke fixture contract * test(e2e): require silent updater fixture output * fix(release): align stable windows smoke build path * fix(ci): include release workspace in validation * fix(ci): repair release validation lanes Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(ci): restore zero-install Feishu notification Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
b02d20e6b9 |
fix: unify Discord invite links (#4452)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local> |
||
|
|
915548b4bd |
[codex] Fix social template English metadata (#4427)
* Fix social media template English metadata * Remove social template description hard wraps Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
f6cceb303d |
fix(plugins): unwrap cosmetic hard wraps in bundled manifest descriptions (#4406)
Picking a Home example-prompt card (or "Replicate this content" in the plugin detail modal) seeds the composer with the plugin manifest's `description`. Many descriptions were authored with cosmetic hard wraps (a single newline mid-paragraph, ~75 cols, as if formatted for a terminal/markdown source). The composer renders the seed with `white-space: pre-wrap`, so those newlines survived as short ragged lines that never filled the editor width — leaving a large blank gutter on the right of the input box (e.g. the Trading Analysis Dashboard template: 4 hard breaks, ~200px / 29% of the editor blank). Reflow the offending `description` / `description_i18n` strings in the 56 affected bundled manifests into flowing text (wrapped lines joined, real blank-line paragraph breaks preserved; CJK joins carry no space). Surgical string edits only — manifest formatting/key order untouched (146 lines changed across 56 files). The full build spec still reaches the agent as plugin context (SKILL.md + example.html); only the human-facing seed copy changed. Add an e2e guard (plugin-description-hardwrap.test.ts) that fails if any bundled manifest description carries an intra-paragraph hard wrap, so the cleanup can't silently regress when new examples are added. |
||
|
|
eb749841b4 |
fix(home): surface community slide decks on Home with letterbox-free 16:9 previews (#4350)
* fix(plugins): surface slides decks on Home instead of marketplace sources The 23 community slides/deck plugins from #4127 were registered as a restricted community marketplace source, so they showed up as installable "available sources" cards (受限 + Install) instead of on Home. Relocate them to plugins/_official/examples so they ship bundled — appearing in the Home Community gallery and the deck example-prompt rail, exactly like the existing zhangzara / swiss / guizang decks — and drop their community-registry entries. - Move 23 plugins/community/<slug> → plugins/_official/examples/<slug> (upstream LICENSE / author / homepage / "Based on" attribution preserved) - Rename manifest name community-<slug> → example-<slug> (bundled convention) - Remove the 23 entries from plugins/registry/community/open-design-marketplace.json (the 3 pre-existing community entries stay) - HomeHero: uncap the deck example-prompt rail (other chips keep the curated 18) so every bundled slide template is reachable straight from "All" - curatedPriority: pin the 23 slides to the front of both the deck example rail and the Community Slides shelf Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): drop provenance tail from deck seeds & fix deck preview letterbox Two polish fixes for the slide/deck plugins now surfaced on Home: 1. Example-prompt seed: strip a trailing source-attribution sentence ("…。移植自 foo/bar 的 baz 模板。" / "Based on …") from the composer seed so the prompt doesn't end on provenance boilerplate. Conservative — only fires when the final sentence opens with an attribution marker and real text precedes it; attribution woven mid-description (followed by a use-case sentence) and the gallery/detail descriptions are left intact. Latin '.' only ends a sentence at whitespace/EOL so "STYLE_PRESETS.md" / "github.com/…" don't mis-split. 2. Deck gallery preview: decks ship a fixed 16:9 stage that scales to its viewport, so the tall scroll-preview frame letterboxed it and showed a dark --stage-bg band above/below the slide. Tag deck cards with data-od-mode and give them a 16:9 frame the iframe fills natively (no transform, no pan), so the stage sits edge-to-edge with no band. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): deck preview frame to 16:9 so no white strip below the slide The deck preview override targeted the inner html-frame while the gallery frame kept its fixed 300px height, leaving a white strip under the 16:9 slide. Make the gallery frame itself 16:9 for deck cards so the stage fills it exactly — title bar + slide, nothing left over. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(decks): hide the page-counter chrome on all 23 community slide decks The five upstream deck families each render a different page-counter ("1 / 10") — a center pill (.deck-controls), an id="counter" badge, a fixed .deck-counter, or a .count span inside a Shadow-DOM rail — so the home gallery thumbnails showed it inconsistently. Per maintainer request, drop it everywhere rather than unify: inject a display:none rule for the light-DOM counters and inline- hide the Shadow-DOM .count span. Keyboard/touch navigation is untouched; only the visual counter is removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): fix deck letterbox band in the example-prompt rail tiles too The earlier 16:9 deck-preview fix only covered the Community gallery cards; the hero example-prompt rail tiles render the deck in a 4:3 (1440×1080) preview and still showed a dark --stage-bg band on top. Tag deck preset tiles with data-od-mode and give them a 16:9 preview the iframe fills natively, matching the gallery treatment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): remove the ↗ open-external button from community gallery cards The ↗ only rendered when a tile's preview was an HTML source, so it appeared on some cards (most decks, a few prototypes) and not others (images, srcless tiles) — inconsistent chrome across the shelf. Drop it and the whole onOpenExternal pass-through (PluginCard → PluginsHomeSection → HomeView) plus the now-dead .plugins-home__gallery-open styles. * fix(home): make the community search clear (×) button visible The clear button uses the shared <Button> component, whose CSS-module class set padding 6/12 and crushed the 12px × glyph to zero width inside the 26px button (a blank grey square). The .plugins-home__search-clear reset only out-specified the global `button {}` element rule, not the component class — scope it under .plugins-home__search so the padding:0 / 20x20 sizing actually wins. * fix(home): align deck example-prompt tile title row with other tiles Deck preset tiles used a 16:9 `auto` preview row, so their card was shorter than the fixed-150px sibling tiles; the flex rail stretched them back up and the slack leaked into the title row, making deck titles ~6px taller. Keep deck tiles on the standard 150px preview cell and center the native 16:9 stage inside it (neutral margin, no dark band), so card and title-row heights match prototype/HyperFrames/image tiles. * fix(deck-bridge): mirror the visible class so reveal animations fire on navigation Reveal-animation decks (the frontend-slides family) gate staggered entrances on a separate `.slide.visible` class that the deck's own show() adds alongside `.active`. The host bridge's setActive() flipped only the active class, so bridge-driven page turns showed slide chrome but left every .reveal child at opacity:0 — the body rendered blank. Mirror `.visible` in lock-step with the active slide (only for decks that use it, a no-op elsewhere). Adds a red→green regression test. * fix(home): unpin the bare Frontend Slides template from the slides shelf example-frontend-slides is the family-root template with a generic cover; pinned first it read as filler leading the Slides shelf and deck chip. Drop it from PINNED_SLIDE_PLUGIN_IDS so it falls to the uncurated tail while the styled variants (Creative Voltage, Electric Studio, …) keep the lead. --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
c7e422d7a2 |
feat(plugins): unify all 56 official deck seeds with the Open Design product narrative (#4357)
* feat(plugins): unify all 56 official deck seeds with the Open Design product narrative Apply the same canonical 10-section story used for the community slides batch (sourced from the homepage structure doc + README) to every official deck plugin seed that ships an example.html: cover, why, three claims, numbers board (60K+ stars / 300+ contributors / 217+ plugins / 129 design systems / 21 agents), 5-step workflow, multimodal outputs, capabilities, agent ecosystem, testimonial, and CTA with GitHub/Discord/X links. Scenario decks keep their framing with Open Design as the subject: weekly-report/weekly-update become OD growth reports, course-module a getting-started tutorial, testing-safety-alert the local-data-security story, xhs-* decks OD-themed xiaohongshu notes, ib-pitch-book an investor narrative, presenter-mode-reveal keeps its presenter-mode demo. open-design-landing-deck only gets its numbers aligned to the canonical figures. Skipped (no example.html seed): guizang-ppt, html-ppt, replit-deck. Content-only edits: CSS tokens, layouts, decorations, animations, keyboard nav, hash routing and functional JS untouched. zh 13 decks / en 43 decks per existing typography. All 56 verified: script syntax, cover screenshot, no fictional brand residue. * fix(decks): wire dead Download/closing CTAs to real destinations Review follow-up for #4145: primary Download CTAs now point to https://open-design.ai/ (the canonical download landing), and the remaining href="#" closing links (Star on GitHub / Discord / X / See All Agents) point to the repo, Discord invite, and X profile. Also split the landing-deck primary CTA off the repo-root URL so the primary and secondary actions no longer share a destination. * style(official-decks): anti-slop visual pass across the official deck seeds Restyle/polish sweep over all 55 official example decks (taste-skill + impeccable + gsap-skills guidelines): - A-class seeds (AI-slop look: default Inter, purple-blue gradients, uniform rounded shadow cards) fully restyled with distinct typographic systems, locked single accents, and off-white/off-black grounds. - B-class seeds (clear style family, e.g. the zhangzara-* craft set) kept their family signature and received polish only: spacing rhythm, contrast to WCAG AA, hairline discipline, reduced-motion guards. - Motion limited to transform/opacity with prefers-reduced-motion guards; signature ease cubic-bezier(.16,1,.3,1). - Content is unchanged: all copy, numbers (60K+ stars, 217+ plugins, 129 design systems, 21 agents, -80% cost), links, slide counts and the deck engine scripts are byte-identical to the previous seeds. - html-ppt-zhangzara-pin-and-paper already met every rule (craft fonts, single ink accent, static content) and is intentionally untouched. * i18n(official-decks): translate all Chinese deck seeds to English All official slide seeds are now English-only per template policy. 15 decks translated (~12,000 CJK chars): presenter-mode-reveal, testing-safety-alert, xhs-pastel-card, tech-sharing, obsidian-claude-gradient, knowledge-arch-blueprint, xhs-white-editorial, hermes-cyber-terminal, xhs-post, dir-key-nav-minimal, graphify-dark-graph, ppt-keynote, guizang-editorial, swiss-international, open-slide-canvas. - Layout, engine scripts, slide counts, stats (60K+/300+/217+/129/21/ -80%) and links unchanged; only content language changed. - CJK-specific Google Fonts (Noto Sans/Serif SC, ZCOOL KuaiLe, Songti) replaced with Latin families matching each deck's voice (Inter, IBM Plex Sans, Nunito, Patrick Hand, Georgia, Noto Serif). - The xhs-* social decks keep their Xiaohongshu aesthetic with native English social copy. - Overflow from longer English copy fixed with minor per-element type sizing; every deck screenshot-verified; zero CJK characters remain across all 56 official deck seeds. * fix(xhs-pastel-card): restore absolute positioning of topbar/footer chrome The content-layer rule '.slide > *:not(.xp-blob){position:relative}' (specificity 0,3,0) overrode the absolutely-positioned .xp-topbar and .xp-footer (0,2,0), dropping both into the flex flow: the chip overlapped the headline, left:90px turned into a 90px rightward shift that pushed the page number off-canvas, and bottom:40px lifted the footer into the body copy on every slide. Excluding the two chrome elements from the content-layer rule restores the intended layout; verified per-slide screenshots across all 8 slides. * feat(deck-seeds): expand the three sampler decks to full 10-page examples deck-guizang-editorial, deck-swiss-international, and deck-open-slide-canvas shipped as 1-2 page style samplers while every other official seed carries a full 8-11 page example. Each is now a 10-page deck built from its own SKILL.md layout vocabulary: - guizang-editorial: one page per L01-L10 layout, single Ink/Monocle palette per the 5-pick-1 rule, ink/paper reversal for rhythm. - swiss-international: 10 of the 22 locked layouts (statement, cards, six-cell grid, timeline, duo compare, loop diagram, why-now, closing manifesto), Klein Blue as the single accent; SKILL.md example_desc updated from the stale two-page wording. - open-slide-canvas: ten free-composition 1920x1080 canvases (asymmetric split, oversized numerals, positioned-block flow, editorial quote, comparison spread) with keyboard + hash navigation per its own convention. Content follows the English-only OD narrative with canonical stats and links; every page screenshot-verified; zero CJK; single-file with Google Fonts as the only external resource. * fix(decks): wire the two remaining dead closing-slide CTAs Review follow-up for #4145 (nettee, looper reviewer): - 8-bit-orbit: the closing 'Download Open Design' / 'Star on GitHub' pixel buttons were plain <button> elements with no click handling; converted to anchors targeting https://open-design.ai/ and the GitHub repo, keeping the .pixel-btn skin. - retro-windows: the closing copy promised download/star actions but the action row was the old unwired Restart / Contact / End Session set; replaced with Download Open Design / Star on GitHub / Join Discord anchors in the same .btn-retro skin. * fix(decks): wire remaining button-skinned dead CTAs across deck seeds Review follow-up for #4145 (looper reviewer round 3). Converts every remaining action-copy control that carried button/chip skin but no href into a real anchor with the canonical targets, keeping each deck's skin: - zhangzara-long-table: closing .pill chips (GitHub / Download) and the cover 'Star on GitHub' pill - zhangzara-raw-grid: closing .label arrow Download + the two .s10-rb-block tiles (macOS-Windows / Star on GitHub) - zhangzara-peoples-platform: GET STARTED slide DOWNLOAD block - obsidian-claude-gradient: all four .oc-pill chips on the CTA slide - zhangzara-biennale-yellow / sakura-chroma / cobalt-grid colophon ftag labels, zhangzara-pink-script 'Star on GitHub' tile, and ib-pitch-book 'Download Open Design' stamp (same pattern, found by a repo-wide sweep for the regression class) * fix(decks): wire zhangzara-coral closing-slide social icons to anchors * feat(plugins): unify guizang-ppt (magazine-web-ppt) deck default with the Open Design product narrative in English The deck-mode default seed (magazine-web-ppt, dir guizang-ppt) was the one official deck the narrative+i18n pass missed, because its content lives in assets/example-slides.html + assets/template.html rather than example.html. - Rewrite the 9-slide example deck to the English Open Design product narrative (60K+ stars / 300+ contributors / 217+ plugins / 129 design systems / 21 agents / -80% cost), preserving the magazine editorial layout vocabulary and hitting all 8 layout categories. English titles use the Playfair .h-hero-en family; copy follows anti-slop craft (no decorative em-dashes, real labelled metrics, tight hierarchy). - Translate template.html (title, hint, all CSS/JS comments), SKILL.md, references/*.md, open-design.json, and the design-templates README to English. - Keep magazine-web-ppt name, mode=deck, default_for=deck intact. - Both synced copies (plugins/_official + design-templates) updated identically. --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> |
||
|
|
a0afc584bb |
[codex] centralize daemon data directory docs (#4222)
* docs: centralize daemon data directory contract * fix(e2e): allow slower artifact consistency navigation Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * docs: localize daemon data directory pointers Generated-By: looper 0.9.5 (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
ec524986b5 |
chore(plugins): remove html-ppt-dir-key-nav-minimal and html-ppt-xhs-post (#4212)
* chore(plugins): remove html-ppt-dir-key-nav-minimal and html-ppt-xhs-post
Final cut list from the maintainer review of the slide-template gallery
(narrowed from the originally proposed nine html-ppt studio seeds to
these two; the other seven stay).
Removed across every surface:
- plugins/_official/examples/<slug>/ (2 plugin dirs)
- design-templates/<slug>/ (2 catalogue entries)
- plugins/registry/official/open-design-marketplace.json entries
- apps/web/src/i18n/content{,.ru,.fr}.ts slug keys
Landing-page solution showcases never referenced these two, so no
landing changes are needed. pnpm guard and pnpm typecheck pass;
repo-wide grep for both slugs returns zero hits.
* fix(registry): sync bundledPreinstallCount after removing two plugins
plugins-marketplaces.test.ts asserts metadata.bundledPreinstallCount
equals the registry plugins array length; update 414 -> 412 to match
the two removed entries.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
|
||
|
|
b034609cde |
chore(plugins): remove the shamoni example plugin (duplicate preview imagery) (#4040)
* chore(plugins): remove the shamoni example plugin The Shamoni scroll-driven gallery example ships a baked preview that duplicates luxury-botanical's hero imagery, so the Community shelf shows the same perfume tile twice. Curator call: drop the example entirely — plugin folder, baked-preview manifest entry, and its slot in the pinned curated ordering. * fix(daemon): prune persisted bundled rows when their folder leaves the image The bundled boot walker only upserted folders that still exist, so a plugin removed from the daemon image (like the Shamoni example this PR deletes) survived in upgraded installs' installed_plugins table — and /api/plugins kept serving a record whose backing files were gone. Make bundled rows mirror the bundled tree: after a successful walk, delete source_kind='bundled' rows whose folder was not seen this boot. Folders that still ship but fail to parse stay registered (warned, not pruned), the ENOENT early-return never prunes (a missing bundledRoot is a packaging bug, not a removal), and user-installed rows are untouched. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
ec47346e94 |
feat(web): composer 插件菜单 & 设计百宝箱 hover 预览 (#4000)
* feat(web): hover-preview column in the composer plugins menu
Hovering (or arrow-defaulting to) a plugin in the composer "+" → Plugins
flyout now opens a second-level preview column: a live preview hero
(reusing the plugins-home PreviewSurface — media poster or sandboxed
example iframe) plus the localized title, trust badge, description, and
tags. The previewed row stays highlighted so the panel's subject is
clear before the cursor lands.
The Plugins flyout widens to fit the side column and reserves that width
in the placement math; on narrow (contained) surfaces the preview drops
below the list instead. Other submenus are unchanged.
* feat(web): design-toolbox hover preview + styled detail panel
Extends the plugin hover-preview to the project composer's design
toolbox. Hovering a plugin entry now renders the same rich preview
(ComposerPluginPreview — poster / sandboxed example iframe + title,
trust badge, description, tags); every other kind (skill, MCP,
connector, file, follow-up action) keeps a compact text card.
The shared hover-detail panel (.plus-menu__detail) previously shipped
with no CSS at all — it had no position/background/border, so the
inline left/top never applied. This adds the panel styling (fixed,
panelled, shadowed, viewport-clamped) plus the section-label and
detail text styles, and clamps the panel's top so the taller plugin
preview stays on screen. ComposerPluginPreview's column divider was
de-scoped to the plugins-flyout context so it renders cleanly inside
the toolbox panel too.
* fix(web): drop redundant divider above design-toolbox search
The toolbox head carried a border-bottom while the search box below it
has its own full border, so with the flyout gap the two hairlines read
as a doubled line. Drop the head border; the search box already bounds
the section.
* fix(web): localize plugin titles in the composer plugins list
The list rendered the raw `plugin.title` (often English) while the
hover preview used the localized `title_i18n`, so the same plugin showed
two different-language names side by side. Render the localized title in
the list too, and fold it into the search haystack so a localized-name
query still matches.
* feat(web): show plugin kind tag in the hover preview
Adds a localized kind pill (Prototype / Slides / Image / Video / Audio /
HyperFrames / Live artifact) to the plugin preview title row, reusing
extractCategories — the same taxonomy that powers the home Community
filter chips — so the preview names the plugin's type at a glance. Shows
in both the composer plugins menu and the design-toolbox preview.
* fix(web): localize the applied-plugin chip title
The composer's applied-plugin chip showed the raw `record.title` (English,
e.g. "Audio Jingle") while the same plugin's preset card / hover preview
used the localized `title_i18n` (e.g. "音频铃声"), so the two read in
different languages. Localize the chip in both surfaces:
- HomeView: activeBadgeTitle now uses localizePluginTitle(locale, record).
- PluginsSection: the ContextItem label (project ChatComposer chip) too.
Mirrors the already-correct PluginPromptPresetCard pattern.
* fix(web): localize trust badge, drop raw tag chips from preview
- TrustBadge now resolves its label via i18n (pluginsView.trust.*) so
Official / Trusted / Restricted follow the active locale everywhere it
renders; an explicit `label` prop still overrides.
- Drop the raw manifest tag chips from the plugin hover preview. Tags are
author-defined English slugs with no controlled vocabulary, so they
can't be reliably localized; the localized kind pill already conveys
the category, so the card stays single-language.
* feat(web): tag design-system plugins in the hover preview
Design-system plugins aren't one of the home Community facets, so
extractCategories returns nothing and they had no kind pill. Detect them
by mode/tag (same heuristic as the preview classifier) and show the
localized 'Design systems' label (entry.navDesignSystems).
* i18n(plugins): backfill title/description translations for 22 example plugins
These 22 official example manifests shipped title_i18n / description_i18n
with only zh-CN + en, so in every other UI language (Korean, Japanese,
…) the plugin name and description fell back to English — visible now
that the composer surfaces them in the hover preview.
Fill all to the full 18-locale set (zh-CN, zh-TW, ja, ko, de, fr, ru,
es, pt-BR, it, vi, pl, id, nl, ar, tr, uk, en), matching the locale set
used by the already-complete manifests. Brand/product/proper names and
technical terms are kept verbatim; useCase.query stays English-authoritative.
* fix(web): clamp design-toolbox detail panel into the viewport
The left-side fallback (when the right side overflows) used
rect.left - gap - detailWidth without clamping, so a row near the left
edge or a pane narrower than detailWidth + gap*2 produced a negative
left and pushed the position:fixed panel off-screen. Clamp the chosen
left into [8, innerWidth - 8 - detailWidth] so it always degrades
gracefully. (review: nettee/looper)
* test(web): extract + unit-test toolbox detail panel positioning
Pull the detail-panel placement out of showToolboxDetail into a pure
computeToolboxDetailPosition helper and pin the narrow-pane clamp with a
focused vitest regression (row near left edge / viewport narrower than
the panel never yields a negative left; top clamps too). Addresses the
nettee/looper review ask for a regression check.
* fix(web): match plugins-flyout placement reserve to rendered width
PLUS_MENU_PLUGIN_FLYOUT_WIDTH was 560 while .plus-menu__flyout--plugins
renders at 466px, so getFlyoutPlacement over-reserved and medium-width
panes (~664-757px side room) wrongly fell back to the contained layout,
silently dropping the side-by-side preview column. Set it to 466 (with a
cross-reference comment to the CSS), extract the boundary arithmetic into
a pure resolveFlyoutSide helper, and pin the 466-vs-560 boundary with a
vitest regression. (review: nettee/looper)
* fix(web): localize trust badge tooltip + aria text
title and aria-label still came from the hard-coded English
meta.description, so on non-English locales the badge read as
mixed-language to tooltips and screen readers. Resolve all of label,
title, and aria-label from the localized tier key. (review: nettee/looper)
* fix(web): update TrustBadge test for localized a11y text
The existing TrustBadge spec asserted the old hard-coded English
descriptions ("Open Design official", aria "…: Action plugin"), which the
localization change replaced — that's why Web workspace tests went red.
Keep a localized tier prefix in the accessible text when a contextual
label is passed ("Official: Action plugin") and update the spec to pin
the localized behavior.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
|
||
|
|
b8489c9874 |
fix(plugins): pin the Motion React UMD loader in motionsites plugins (follow-up to #3973) (#3992)
* fix(plugins): pin Motion React UMD loader in plugins, generalize the system-prompt rule PR #3973 patched the blank-screen crash (Motion React hooks loaded from the vanilla motion.js DOM bundle) at the runtime/write boundary and added a Framer Motion note to the official system prompt. This closes the remaining gaps: - Root cause was in the plugins, not just the runtime: the 25-plugin motionsites batch (#3873) prescribes Framer Motion hooks in the React port but never locks how to load them, exactly as it locks fonts/colors/asset URLs. Add a "Motion loading (locked)" note to the 8 plugins that genuinely prescribe Framer Motion (3d-creator-portfolio, acreage-farming, evergreen-finance, liquid-glass-agency, luxury-botanical, mindloop-landing, portfolio-cosmic, shamoni). Plugins that map useScroll *down* to a passive listener, or use GSAP only (cinematic-landing-page), are intentionally left untouched. - Generalize the system-prompt note to lead with the principle (two UMD builds: vanilla DOM vs React, hooks live only on the React build's window.Motion) while keeping one pinned example version. - Add port-path regression coverage for the reported luxury-botanical plugin: full Motion hook set (useScroll/useTransform/useAnimationFrame/useMotionValue), the minified vanilla bundle, and the wrong-bundle + FramerMotion-global combo. Validation: pnpm guard, contracts + daemon typecheck, daemon artifact-runtime-compat.test.ts (8/8). * fix(daemon): widen Motion UMD normalizer to jsdelivr + wrong-file shape The runtime normalizer only matched the exact unpkg `motion@VER/dist/motion.js` script shape, so two real agent outputs still slipped through to a blank screen: a vanilla bundle served from jsdelivr, and the right package name pointing at the wrong file (`framer-motion@VER/dist/motion.js`). Widen the matcher to both hosts and both package spellings, preserve the original CDN host on rewrite, and document the `<script src>`-only boundary (ESM imports / importmaps / esm.sh are steered by the prompt + plugin notes, not rewritten). The React-hook usage gate still keeps animate-only vanilla DOM artifacts untouched, and a new test pins that the correct framer-motion.js bundle is never falsely rewritten. --------- Co-authored-by: audit <a@b.c> |
||
|
|
75f1472d53 |
feat(web): align Home composer facet rails with Community + drop 6 low-quality example templates (#3939)
* feat(web): align Home composer facet rails with Community + drop 6 low-quality example templates Home composer sub-category rails now mirror the Community plugin grid exactly — same sub-category set, order, and per-facet plugin slice: - Prototype order: Landing/marketing, Brand/design, Dashboards, Apps, Developer tools, Docs/reports - Slides order: Creative decks, Engineering talks, then Pitch/business, Course/training, Reports/briefings, Product/sales - Sub-chips are derived from the full install set (not the curated example subset), so the rail shows every type Community shows - Selecting a sub-category now lists the same plugins Community lists for it via applyFacetSelection (primary-category + sub-category match), so the example-prompt count matches the Community count badge Also removes six example templates with broken/poor visuals (Art Landing, Prisma Creative Studio, Urban Jungle, Modern Agency, AI Automation, FlowMate) and their pinned-order entries in curatedPriority. * fix(web): separate facet display order from matching precedence Addresses review: reordering SUBCATEGORIES re-bucketed overlapping-tag plugins because extractSubcategories() resolves via SUBCATEGORIES.find() (first match wins). Dashboards/app/launch-deck plugins with secondary design/marketing tags wrongly moved into Brand / design or Creative decks in both Home and Community. - Restore SUBCATEGORIES to its original matching precedence (stable buckets) - Add SUBCATEGORY_DISPLAY_ORDER, applied in buildSubcategoryCatalog, so the rails/catalog render Landing/Brand/... and Creative/Engineering/... first without changing which bucket a plugin lands in - Add regression coverage in plugins-home-facets.test.ts for overlapping-tag fixtures (dashboard+design, mobile+design, landing+brand, launch+marketing, pitch+marketing) and update the display-order expectations --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
bad35b45c9 |
fix(daemon): stabilize HyperFrames render handoff (#3882)
* fix(daemon): stabilize hyperframes render handoff * fix: align hyperframes skill handoff guidance --------- Co-authored-by: audit <a@b.c> |
||
|
|
a93869ee09 |
feat(plugins): 25 motionsites example plugins + daemon asset cache (#3873)
* feat(plugins): add 25 motionsites example plugins + daemon asset cache Add 25 first-party example scenario plugins under plugins/_official/examples/ (packaged from motionsites.ai templates via the motionsites-to-open-design-plugin skill): each ships open-design.json, SKILL.md, and a self-contained rendered example.html fidelity seed. All 25 pass PluginManifestSchema. Their cross-border CDN images/videos (cloudinary, higgs.ai, motionsites, cloudfront) are mirrored to Cloudflare R2 (plugin-assets.open-design.ai) and high-fidelity compressed (732MB -> 302MB), so example.html / query / SKILL.md reference the fast public origin instead of slow cross-border hosts. Daemon asset cache (plugin-asset-cache.ts + /api/asset-cache): a same-origin disk-cached proxy for any external preview media that remains. The preview URL rewriter now routes external media (src/poster attrs, CSS url(), and JS string constants) through it, so cross-border assets satisfy the sandbox CSP (img-src 'self') and load from local cache. SSRF-guarded: http(s) only, no credentials, and every resolved address must be public. * fix(asset-cache): tie SSRF validation to the actual outbound connection The previous guard resolved DNS in assertSafePublicUrl and then let fetch() resolve again independently, so a DNS-rebinding host could pass the validation lookup with a public address and steer the real connection to a private one (e.g. 169.254.169.254). Move the authoritative check to a connection-time undici Agent lookup (createValidatingLookup): the address that is validated is the exact address the socket connects to, closing the TOCTOU gap. assertSafePublicUrl is now a cheap up-front reject (scheme / credentials / localhost / literal private IP) only. Adds createValidatingLookup unit tests (public pass, rebinding-to-private reject, all:true any-private reject). * fix(asset-cache): reject IPv4-mapped IPv6 literals in the private-IP guard Node's URL parser normalizes a bracketed mapped literal like `http://[::ffff:127.0.0.1]/` to the hex form `::ffff:7f00:1`, which the old dotted-decimal regex missed — so a literal mapped host slipped past assertSafePublicUrl (and literal IPs skip the DNS lookup hook), letting `/api/asset-cache` target loopback/private IPv4 via its mapped representation. Canonicalize IPv6 now: expandIpv6() folds `::` compression and any embedded dotted IPv4 into eight 16-bit groups, and isPrivateAddress() detects the full `::ffff:0:0/96` mapped range (hex or dotted), feeding the embedded IPv4 back through the v4 private-range checks. Group-based classification also replaces the prefix string-matching for ::, ::1, fe80::/10, fc00::/7, ff00::/8. Regression coverage added for ::ffff:7f00:1 / ::ffff:127.0.0.1 and http://[::ffff:127.0.0.1]/x.png. * fix(asset-cache): full link-local range + stream-cap the upstream body Two SSRF/DoS hardening fixes on the cache path: - Link-local was matched as the single fe80:: prefix, leaking the rest of fe80::/10 (fe90::, febf::, …) through as "public". Classify with a mask ((groups[0] & 0xffc0) === 0xfe80); ULA/multicast use masks too now. - maxBytes was not a hard ceiling for responses without a trustworthy Content-Length: arrayBuffer() buffered the whole body before the size check, a memory-exhaustion path for a caller-supplied proxy. Stream the body and abort the moment the accumulated size exceeds maxBytes, before concatenating. Tests: fe80::1 / fe90::1 / febf::1 rejected; a no-Content-Length 800-byte stream against a 16-byte cap rejects with 413 after <10 pulls (proves it stops reading instead of buffering the full body). --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
10dfd32a3e |
Revert "feat: add screenshot-based visual validation to critique loop (#3660)" (#3865)
This reverts commit
|
||
|
|
931780c914 |
feat: add screenshot-based visual validation to critique loop (#3660)
* feat(daemon): add visual validation atom Generated-By: looper 0.9.3 (runner=worker, agent=codex) * fix(daemon): fail closed in visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): narrow visual validation defaults Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): add visual validation to default critique stages Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): harden visual validation review fixes Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed in visual validation discovery Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * test(daemon): tighten visual validation discovery regression Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): match visual validation reference viewport Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): tighten visual validation capture flow Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed across visual validation refs Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): honor metadata entry file in visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): capture visual validation through preview route Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed without preview context Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): disable pre-start visual validation worker Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): narrow visual validation spec discovery Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): stop advertising visual validation as runnable Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): restore visual validation critique worker Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): delay visual validation until run success Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * test(daemon): cover post-run visual validation scheduling Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): gate post-run visual validation before finish Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * chore(nix): refresh pnpm deps hash * fix(daemon): preserve deferred pipeline ordering Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): bundle Chromium for visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(scenarios): keep visual validation out of default critique loop Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): bundle Playwright headless shell Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): invalidate Playwright resource cache Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): include visual-validation in bundled atom roster Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * chore(nix): refresh pnpm deps hash * fix: restore pre-run plugin surfaces and nix hashes Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: preserve pre-run surfaces and tolerate headed-only chromium bundles Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: launch visual validation with bundled chromium Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: avoid Playwright fixture teardown races Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: fail packaged visual validation on shell-only chromium Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: isolate synthetic Playwright test bundles Generated-By: looper 0.9.5 (runner=fixer, agent=codex) --------- Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com> |
||
|
|
df9ec8f40d |
examples: add 3D creator portfolio and Velar luxury real-estate templates (#3817)
* examples: add 3D creator portfolio and Velar luxury real-estate templates Two first-party motionsites.ai template seeds under plugins/_official/examples/, each shipping the manifest + locked SKILL.md spec + a self-contained rendered example.html fidelity anchor. - example-3d-creator-portfolio: dark gradient-text hero with a magnetic 3D portrait, scroll marquee, char-reveal About, and sticky-stacking project cards. - example-velar-luxury-real-estate: typewriter preloader, scroll-driven building that scales up while pinning to a dark stats band, count-up stats, and a hover-expand video gallery. Fixed decoration/portrait images are inlined as compressed WebP data URIs so the card and detail previews never break in the sandbox; large GIFs/videos and stable -CDN backgrounds stay as remote URLs. Both manifests validate against PluginManifestSchema (od.kind=scenario). * examples: use first-party metadata for motionsites templates Align the 3D creator portfolio and Velar manifests with the first-party metadata contract used by the rest of plugins/_official/examples/** (MIT, author Open Design, repo homepage) instead of CC-BY-4.0 / third-party motionsites provenance. Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code) * examples: point all inlined-asset references in the locked query at example.html The per-section spec in od.useCase.query.en still named the original remote hosts (figma.site portrait/decorations, cloudinary HOUSE_IMG) as the asset source, while only the trailing note said to reuse the inlined data URIs. Since the query is the authoritative generation brief injected on Use, a port could copy the deprecated remote URLs and regress to sandbox-403 / broken images. Rewrote those references to instruct reusing the inlined data:image/webp URIs from example.html. Genuinely-remote assets on stable CDNs (the 21 motionsites marquee GIFs, 9 higgs project images, 5 cloudfront gallery videos, the higgs hero background) are unchanged. * examples: align Velar nav dark-section refs in the locked query with the seed The Fixed Navigation bullet in od.useCase.query.en said the nav-color logic watches "Section 4 and Section 5", but the seed and SKILL.md define the dark sections as Section 5 (dark statement band) and Section 6 (gallery). Since the query is injected as the generation brief, the stale ref could make a port watch the wrong sections and leave the nav dark over the gallery. Updated the string to match the seed/skill wording. * examples: give the 3D portfolio nav links real anchor targets The hero nav shipped #price and #contact links with no matching ids in the seed, so half the navbar did nothing in the preview (and ports would inherit the dead links). Added id="price" to the Services section and a minimal contact footer (id="contact") so all four nav anchors resolve to real targets. The four-link names stay as the prompt specifies; only the seed gains anchors. * examples: document the 3D portfolio contact footer in the locked query and skill The previous fix added a #contact footer to example.html but left the injected query and SKILL.md describing only five sections (no contact target), so a port could still recreate a dead #contact anchor. Added the Contact footer section to the SECTION ORDER, a nav→anchor mapping (every link must resolve), and a Contact Section spec in both od.useCase.query.en and SKILL.md so the prompt, skill, and seed all agree. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
0d84245b98 |
feat(plugins): add Dashboard UI — Liquid Glass first-party prototype preset (#3779)
* feat(plugins): add Dashboard UI — Liquid Glass first-party prototype preset Bundle a premium liquid-glassmorphism conference dashboard as an official example prototype plugin. Picking it routes the plugin as the active driver and reproduces the template: dual theme-swapped fullscreen background videos, a 4x2 glass/solid card grid, animated voice-wave participant indicators, and a floating control bar. - od.kind: scenario with its own generate pipeline (file-write + live-artifact) and the full build spec in od.useCase.query so the agent reproduces the design. - Ships a rendered, self-contained example.html seed as the fidelity anchor and the HTML preview entry; the marketplace card uses the motionsites animated webp poster. - All 30 avatars are inlined as base64 SVG data URIs so the preview never breaks on external avatar-host rate limits inside the sandbox; background videos and screen-share thumbnails stay on stable CDNs. * fix(plugins): make dashboard-ui-glass avatar instructions consistent with the inlined seed The top-of-file "Avatars (critical)" rule says to keep the bundled data: URI avatars, but the Profile button and Meeting alert bullets still named api.dicebear.com remote URLs — conflicting guidance that could lead a React/Vite export to ship broken sandbox avatars. Both bullets now say to reuse the corresponding inlined avatar from example.html. * fix(plugins): drop dashboard-ui-glass zh-CN query override so it falls back to the full English brief resolvePluginQueryFallback picks od.useCase.query['zh-CN'] ahead of the English fallback, so the shortened Chinese string became the entire generation brief for zh-CN users — dropping the locked avatar/network rules, the card-by-card layout, and the interaction details the English brief carries, and producing a materially different dashboard under a Chinese locale. Remove the zh-CN query override so Chinese users fall back to the authoritative, complete English brief. title_i18n / description_i18n (marketplace display strings) are unaffected. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
071db7ca1b |
[codex] Stabilize HTML deck navigation state (#3142)
* fix: stabilize html deck navigation state * fix: avoid misclassifying transform decks as scroll decks * fix: detect default root-scroller decks --------- Co-authored-by: Nongzi <3051966228@qq.com> |
||
|
|
d0921ed335 | fix(skills): avoid orphan web prototype files (#3253) | ||
|
|
f8c860a505 |
feat(landing-page): localize plugins library across 18 locales (#3010)
* feat(landing-page): localize plugins library across 18 locales PR #2926 shipped the new `/plugins/` library hub + four kind sub-routes + detail pages, but the chrome was English-only — visitors landing on `/zh/plugins/` saw the old marketplace registry placeholder rendered by the catch-all instead, and detail pages rendered identical English copy regardless of locale prefix. This PR brings the plugin surface to feature parity with `/zh/skills/`, `/zh/templates/`, `/zh/systems/`, `/zh/craft/`. ## What changes - New `app/_lib/plugins-i18n.ts` — single source for all plugin chrome copy (hub, list pages, chip rails, share dialog, detail-page meta labels). English baseline + 17 locale overrides keyed on `LandingLocaleCode` (the same short-code shape `localeFromPath()` returns). Missing keys per locale fall back to English so a partially-translated locale still renders sensibly. Translations cover hub copy, four tile titles + blurbs, seven artifact-kind labels + descriptions, 23 scene-subcategory labels, 18 detail-page chrome strings, and a six-key share-dialog table with a per-locale `shareTemplate({title, url})` function (translated for every locale where `_lib/i18n.ts` already had one — same voice). - `app/pages/plugins/{,templates/,templates/[kind]/,skills/,systems/, craft/,[slug]/}/index.astro` — every hardcoded English string now reads `getPluginsCopy(locale)` keys. Page logic and routing unchanged. - New short-code wrappers under `app/pages/[locale]/plugins/` — six files (hub + three sub-routes + `[kind]/` and `[slug]/`) following the same pattern `[locale]/skills/index.astro` already uses: each re-exports the canonical page component and adds a per-locale `getStaticPaths()` so the build emits 17 locale prefixes per plugin route. Total plugin-route prerender count goes from ~390 to ~7 000, matching the existing skill/template scaling. - Catch-all (`[locale]/[...path].astro`) — old `getPublicPlugins` / `getRegistryCounts` registry rendering removed (placeholder UI that was never wired to a real marketplace data source). Plugin routes now live exclusively under `[locale]/plugins/...` short-code wrappers, so the catch-all stops claiming `'plugins'` as a route root. The dead-code path also drops a `pluginCounts.all` reference the title row was reading. - `.plugins-tile-grid` styles promoted from a scoped `<style>` in the default-locale hub to global `app/sub-pages.css` so the short-code wrapper renders the same hub markup without re-mounting per-page CSS — `display: contents`-style scoping pitfalls in Astro's per-component CSS scoping made this the cleanest fix. ## Surface area - [ ] **UI** — new page / dialog / panel / menu item / setting / empty state in `apps/web` or `apps/desktop` - [ ] **Keyboard shortcut** — new or changed - [ ] **CLI / env var** — new `od` subcommand or flag, new `tools-dev` flag, or new `OD_*` env var - [ ] **API / contract** — new `/api/*` endpoint, new SSE event, or changed shape in `packages/contracts` - [ ] **Extension point** — new entry under `skills/`, `design-systems/`, `design-templates/`, or `craft/`, or change to the skills protocol - [ ] **i18n keys** — new translation keys (full plugin chrome added across all 18 locales) - [ ] **New top-level dependency** — adding any new entry to the **root** `package.json` - [ ] **Default behavior change** — changes what existing users experience without opting in - [x] **None** — landing-page-only restoration of i18n parity for the plugin surface ## Validation - `pnpm --filter @open-design/landing-page typecheck` → 0 errors - `pnpm --filter @open-design/landing-page build:static` → 16 127 pages built (+6 584 over current main: ~388 plugin detail pages × 17 locale prefixes plus the hub + four sub-routes × 17 locales). - `copy-example-html.ts` reports `266 entry files + 65 referenced files`, identical to before — no regression in the asset-mirroring pipeline. - Local Playwright smoke (`/zh/plugins/...`): - `/zh/plugins/` renders `<title>插件库 · Open Design</title>`, label `插件库`, h1 `407 个可组合的构件。`, four tiles labelled `模板 / 技能 / 设计系统 / 工艺`. - `/zh/plugins/templates/video/` renders h1 `48 视频`, scene chips `全部 / 动效 / 短视频 / 营销 / 产品 / 数据讲解`. - `/zh/plugins/example-article-magazine/` share dialog renders `复制下面的文案、然后跳到你想分享的平台粘贴即可` etc., share template auto-interpolates plugin title + URL into Chinese voice. - All 18 locale prefixes (`/zh`, `/zh-tw`, `/ja`, `/ko`, `/de`, `/fr`, `/ru`, `/es`, `/pt-br`, `/it`, `/vi`, `/pl`, `/id`, `/nl`, `/ar`, `/tr`, `/uk`) → 200 across hub + four sub-routes + sample detail page. - English `/plugins/` unchanged (default-locale path bypasses the `[locale]/...` wrapper). * feat(landing-page): finish plugins i18n chrome across 18 locales The first localization pass shipped a partial fix: hub headings, lead copy, two-level page chrome, detail-page metadata labels, the share dialog, and the chip rail were still falling back to English on every non-English locale because plugins-i18n.ts only filled a chrome slice for `zh` and the file header even claimed "7 artifact-kind labels and 25 scene-subcategory labels are translated" for every locale that did not yet have those blocks. Three changes close the visible gap: 1. plugins-i18n.ts: fills the 27 still-missing chrome fields per locale for zh-tw / ja / ko / de / fr / ru / es / pt-br / it / vi / pl / id / nl / ar / tr / uk. Includes the 7-key category map, the 23-key subcategory map, hubHeading / hubLead, the 4 *Label / *Heading / *Lead triples for the templates / skills / systems / craft hub pages, the 4 tile blurbs, the 4 browse buttons, sceneLabel, allChip, the 12 detail-page metadata labels (mode / scenario / platform / surface / author / manifest id / tags / preview caption / find on GitHub / homepage / open in new tab) and bucket label map, the detail share dialog (title / copy link / jump-to), and the header-side nav.plugins entry. zh receives the same 11 detail-page and share-dialog labels it was also missing. 2. header.tsx + site-footer.astro: routes the hardcoded "Plugins / Templates / Skills / Systems / Craft" labels through `nav.*` from HeaderCopy, so every locale gets its own dropdown trigger and footer column. Adds `nav.plugins` to HeaderCopy and fills it in 18 locales with the local form ("插件" / "プラグイン" / "Plugins" / "Plug-ins" / "Plaginy" / "الإضافات" / etc). 3. plugin-row.astro + content-i18n.ts: chip rail. The bundled-plugin branch now runs raw `mode` / `scenario` slugs through the shared localizeTaxonomyValue, and that helper now also consults the plugins-i18n subcategory map before giving up. localizeTaxonomyValue now returns undefined on a true miss instead of the unknownTag placeholder, so chips drop quietly instead of showing "Category" / "分類" / "Categoría" for taxonomy slugs we have not localized yet. Callers that genuinely want the placeholder (`localizeContentTag`, blog `category`, system noun) still keep the explicit fallback. Out of scope and tracked separately: per-plugin title and description in plugins/_official/* (author-supplied English metadata, ~401 plugins without an i18n schema in the manifest yet — needs RFC + tooling before the manifests can be expanded), and adding the long tail of mode / scenario / category slugs (`code-migration`, `plugin-sharing`, `tune-collab`, `live-artifacts`, `engineering`, ...) to TAXONOMY_TERMS so chips render localized labels for every taxonomy value rather than dropping silently. * feat(landing-page): cover plugins chip rail long-tail taxonomy slugs PR #3010's first round localized the high-frequency mode/scenario chips (prototype, video, image, marketing, design, ...) but left the ~37 mode/scenario and 14 category slugs that show up in real `od.*` metadata — code-migration, plugin-sharing, design-system, planning, scenario, refine, discovery, handoff, token-map, tune-collab, orbit, live-artifacts, engineering, healthcare, hr, sales, support, default-router, downstream-export, figma-migration, media-generation, plugin-authoring, validation, 3d-shaders, animation-motion, audio-music, creative-direction, design-systems, diagrams, documents, image-generation, marketing-creative, screenshots, slides, video-generation, web-artifacts, ... — falling through to undefined and dropping their chip silently on every non-English locale. The data layer is the source of truth here, so this expansion lands in `content-i18n.ts:TAXONOMY_TERMS` / `CATEGORY_LABELS` rather than the plugins-i18n catalog: a single dictionary entry per slug fans out to every chip-rail consumer (catalog rows, detail metadata, the templates/[kind] facets) without each consumer touching its own copy. Translations cover all 17 non-`en` locales. Brand and product nouns (Figma, Open Design, BYOK, plugin) stay literal; technical taxonomy slugs get short equivalents that read as chips rather than full prose. The result on `/ja/plugins/skills/` matches `/plugins/skills/` chip-for-chip (30 chips both sides) instead of dropping 27 of them the way the previous iteration did. * feat(landing-page): read manifest title_i18n / description_i18n on bundled plugins PR #3010's prior rounds localized chrome and chip rails but the catalog's most prominent text — each row's plugin name and blurb — stayed English on every non-English locale. The plugin manifest schema (`packages/contracts/src/plugins/manifest.ts`) has supported `title_i18n` and `description_i18n` (Record<locale, string>) on every manifest from spec v1; ~24 of the 401 first-party manifests already carry one for `zh-CN`. The reader was just never wired to use them. This change does the reader half: bundled-plugins.ts captures the two i18n maps off each `open-design.json`, plugin-row.astro and the detail page resolve them at render time via two new helpers (`resolveBundledTitle`, `resolveBundledDescription`) that mirror the short→long fallback chain documented in the manifest spec (`htmlLang` like `zh-CN` → short `LandingLocaleCode` like `zh` → primary tag → `en` → English baseline). The static-paths pass still runs once for all locales — it has to, since each manifest produces one URL — but the title/description shown on the rendered page now reads the locale off `Astro.url.pathname` and picks the right entry out of the maps. Verified locally: `/zh/plugins/example-card-twitter/` now reads "Twitter 分享卡 / 推特金句 / 数据卡, 适合配推文" from the manifest's existing `zh-CN` block instead of the English baseline. Plugin-data half follows in a separate commit. The 17 non-English locales × 401 manifests need backfilling so the reader has something to resolve to; that's data, not schema, and lands as a sequence of manifest patches rather than tangled with this code change. * feat(plugins): translate scenarios bucket title/description across 17 locales Closes the first chunk of #3028. Eleven scenarios plugins (the default-scenario bundle for each taskKind: code-migration, figma-migration, media-generation, new-generation, tune-collab, plugin-authoring; the default design router; the React / Vue / Next.js downstream-export starters; and the Refine baseline) get title_i18n + description_i18n filled for all 17 non-English locales the landing page serves (zh-CN, zh-TW, ja, ko, de, fr, ru, es, pt-BR, it, vi, pl, id, nl, ar, tr, uk). The reader landed in 7ddfe36; this commit is data-only. taskKind slugs that other docs reference by name (`code-migration`, `figma-migration`, `tune-collab`, etc.) stay literal in the descriptions so cross-references still resolve. Brand nouns — Open Design, Next.js, React, Vue, Figma — also stay literal. `/ja/plugins/od-code-migration/` now reads "コードマイグレーション(デフォルトシナリオ)" instead of the English baseline; `/zh/plugins/skills/` shows "代码迁移(默认场景)" in the catalog row. Remaining buckets (image-templates 45, video-templates 50, examples 140, design-systems 142 = 377 plugins) follow in subsequent commits in this PR. * fix(landing-page): drop CJK template wrap when source name is still English The Chinese / Japanese / Korean fallback templates for craft, skill, template, system, plugin, and blog text splice the source `name` / `title` into a CJK sentence frame: ``${name}工艺规则``, ``Open Design 指南:${topic}``, ``${name} は…のスキルです``. When the underlying SKILL.md / craft markdown / blog frontmatter still ships an English name (true for ~95% of the catalog today), that produces mid-sentence script straddling on `/zh/...`, `/zh-tw/...`, `/ja/...`, `/ko/...` like: H1 : "Editorial typography hierarchy工艺规则" Lead : "这条 Open Design 工艺规则定义 Editorial typography hierarchy 的执行标准…" Plug : "video 插件 · 3D Animated Boy Building Lego" That reads worse than the all-English fallback, because the visitor parses the page in two scripts at once. Adds a `nameNeedsEnglishFallback` guard that fires for the four CJK locales whenever the spliced-in name has no CJK characters of its own, and threads it through every `localizeXxxText` helper: craft, template, system, plugin, skill, blog. When it fires the helper returns the raw English content untouched, so the section renders end-to-end in one language. Chrome (header, footer, breadcrumb, buttons, share dialog) keeps its CJK rendering — only the title-and-lead block falls back. Side benefit: the same guard kicks in on the long tail of plugin manifests still pending `title_i18n` / `description_i18n` backfill (tracked in #3028), so `/zh/plugins/<bundled>/` no longer pairs a "video 插件 · 3D Animated Boy Building Lego" title with a Chinese breadcrumb. The page reads "3D Animated Boy Building Lego" + the English manifest description, while header / footer / breadcrumbs stay localized. Once a manifest ships its i18n maps, the chrome and body re-converge automatically. Non-CJK non-Latin scripts (ar, vi, ...) keep the previous behavior — their templates already read tolerably with English names. If that turns out to be wrong on a real audit, the same guard generalizes by adding the matching Unicode range and locale set. * feat(plugins): translate image-templates bucket title/description across 17 locales 44 of 45 image-templates plugins get title_i18n + description_i18n filled for all 17 non-English locales (zh-CN, zh-TW, ja, ko, de, fr, ru, es, pt-BR, it, vi, pl, id, nl, ar, tr, uk). Generated via Claude Sonnet 4.5 over the OpenRouter gateway, ~$1.38 in API spend, 156s wall-clock. Brand and cultural references stay literal (Open Design, Lego, Hanfu, Showa, Pokémon, Black Myth: Wukong). Long AI generation prompts collapse to a 1-2 sentence summary capturing what the plugin does — the description doubles as catalog blurb on the landing site, not as the actual generation prompt (which lives in example.html / the manifest's preview entry). Skipped: `profile-avatar-realistically-imperfect-ai-selfie` returned malformed JSON on three retries; will rerun with a tighter prompt in a follow-up commit. Catalog rows for that plugin keep falling back to the raw English fields per #3010's reader change, so nothing breaks. Tracking: closes the image-templates row in #3028. * feat(plugins): translate video-templates bucket title/description across 17 locales 49 of 50 video-templates plugins get title_i18n + description_i18n filled for the 17 non-English landing locales. Generated via Claude Sonnet 4.5 over OpenRouter, ~$1.47 in API spend, 177s wall-clock. HyperFrames templates, the Three Kingdoms cinematic series, the Seedance/short-film prompts, and the K-pop / wuxia / anime variants all get a 1-2 sentence catalog blurb in each locale; brand and cultural tokens (Black Myth: Wukong, Hanfu, Showa, Pokémon, Three Kingdoms / 三国志, Lego, Disney, K-pop, HyperFrames) stay literal. Skipped: `live-action-anime-adaptation-water-vs-thunder-breathing-duel` returned malformed JSON on three retries; will rerun in followup. Falls back to the raw English fields per the reader landed in |
||
|
|
ceb636aa1b |
feat(landing-page): plugin detail page interactive preview + share dialog (#2958)
* feat(landing-page): plugin detail page interactive preview + share dialog The new `/plugins/<manifest-id>/` detail page that shipped in #2926 landed without the two affordances PR #2679 added to the legacy `/skills/<slug>/` and `/templates/<slug>/` pages: a click-to-expand iframe of the live artifact, and a share dialog with brand-keyword copy plus four-channel jump buttons (X / LinkedIn / Reddit / Facebook). This restores both, sourced from the bundled-plugin manifest under `plugins/_official/<bucket>/<slug>/open-design.json`. ## Interactive preview Three preview-type behaviours, gated on `od.preview.type`: - `video` (Cloudflare Stream URLs already in the manifest) — inline `<video controls poster=...>` with the playable MP4 as `<source>`. Detail-page row is unchanged from #2926; controls double as the open-full affordance. - `html` (a local `example.html` referenced by `od.preview.entry`, only the `examples/` bucket today) — `<details>` toggle wraps the poster image as the summary; clicking opens a sandboxed `<iframe>` that loads the entry HTML lazily, with an "Open in new tab ↗" pill in the frame's top-right corner so the artifact can be inspected at full screen. - `image` or no entry — static `<img>` (existing behaviour). `copy-example-html.ts` is extended to mirror the local entry and any `./assets/...` siblings to `out/plugins/<manifest-id>/<entry>` so the iframe URL resolves on Cloudflare Pages instead of SPA-falling-back to the homepage. The four examples carrying sibling-asset references (flowai-live-dashboard-template, trading-analysis-dashboard-template, open-design-landing, open-design-landing-deck) all render in-place. ## Share dialog Same `<dialog data-share-dialog>` markup the legacy detail pages use, so the global click handlers in `header-enhancer.astro` (`data-share-open` / `data-share-copy` / `data-copy-link`) wire up the open / copy actions automatically — no extra client bundle. Four platform jumps (X / LinkedIn / Reddit / Facebook) plus a Copy-text / Copy-link pair, with a single English template for now (the new `/plugins/...` routes only generate English pages; localisation can land alongside the i18n catch-all follow-up). ## Bundled in - The `copy-example-html.ts` sibling-assets fix from open PR #2880. Without it the existing `/skills/<slug>/` iframe still 404s on Cloudflare Pages for after-hours-editorial-template and the four others; bundling it here means the same script handles both sources in one pass and sidesteps two PRs touching identical helper code. * fix(plugins): remove dangling preview.entry from example-hyperframes The hyperframes example folder ships a SKILL.md (it's an instruction manual for using the HyperFrames HTML format) but no runnable `example.html`. The manifest still claimed `preview.type: html` / `preview.entry: ./example.html`, which made the marketing site try to iframe a non-existent file and forced the preview pipeline into its `Path 3` fallback card — leaving the catalog row visually inconsistent with the eleven sibling `video-template-hyperframes-*` plugins that have real Cloudflare-Stream poster URLs. Drop the preview block entirely so the manifest stops promising a demo it can't deliver. The landing-page detail row continues to render the typographic fallback card (sourced from title / description / mode), which is now the honest representation: "this is an instruction skill, not a renderable template". * fix(landing-page): address PR #2958 review feedback on plugin preview pipeline Two blocking issues called out in code review: 1) `bundled-plugins.ts` exposed `previewEntryUrl` for every manifest that declared `preview.type: "html"`, even when the entry file wasn't shipped. Several first-party manifests fall in this state (example-design-brief's `./brief-preview.html`, example-x-research, example-pptx-html-fidelity-audit, example-hatch-pet, example-last30days, example-guizang-ppt, example-replit-deck, example-live-artifact, example-html-ppt, example-dcf-valuation). The detail page then rendered a click-to-expand iframe and popout link to a file that copy-example-html.ts had skipped, so the iframe URL SPA-fell-back to the homepage on Cloudflare Pages. `entryRelativeUrl()` now `existsSync()`-checks the resolved local path before returning a URL. When the file's missing the detail page falls through to the static thumbnail branch, exactly like plugins that ship no preview entry at all. 2) `copy-example-html.ts` recognised only `(src|href|poster)="./assets/..."` and then bulk-copied the entry's sibling `assets/` folder, so it missed two real ref shapes: bare-relative (`href="assets/styles.css"`, `src="assets/deck-stage.js"` under example-html-ppt-zhangzara-pin-and-paper) and cross-folder (`src="../open-design-landing/assets/hero.png"` under example-open-design-landing-deck). Replaced the heuristic with a generic walker that: - Parses every relative ref in the entry HTML (`(src|href|poster|srcset|data-src)=` plus `url(...)`), splitting srcset on whitespace/commas so multi-URL attrs are honoured. - Resolves each ref against `dirname(entrypointSrc)` for the source and against `dirname(iframeAbsPath)` for the destination — identical to how a browser resolves the same ref against the iframe URL. Files outside the source root or the iframe root are dropped. - Recurses into copied HTML / CSS / JS / SVG so multi-step chains (entry → assets/template.html → assets/fonts/foo.woff) don't strand intermediate files. - Tracks visited *destinations* rather than sources, so a single source that legitimately needs to land at two different out-paths (same-folder copy at /plugins/example-X/assets/foo.png AND a cross-folder copy at /plugins/open-design-landing/assets/foo.png for sibling decks that use `../open-design-landing/assets/foo.png`) gets both copies. Verified manually: - /plugins/example-html-ppt-zhangzara-pin-and-paper/assets/styles.css and assets/deck-stage.js → 200 (bare-relative) - /plugins/open-design-landing/assets/hero.png and assets/about.png → 200 (cross-folder destination, no manifest-id prefix because iframe URL `..` collapses the prefix) - /plugins/example-design-brief/ renders the static thumbnail only, no click-to-expand iframe (broken entry guard) - /plugins/example-flowai-live-dashboard-template/assets/template.html → 200 (existing same-folder behaviour preserved) Build now reports `copied 266 entry files + 65 referenced files`, where the 65 includes both the same-folder `./assets/...` payloads the previous heuristic captured and the bare-relative + cross-folder shapes it didn't. --------- Co-authored-by: Joey-nexu <joeylee12629@gmail.com> |
||
|
|
587f6de46d |
fix: restore Atelier Zero deck plugin prompt (#2822)
Co-authored-by: icc <iccccccccccccc@users.noreply.github.com> |
||
|
|
c14baf07d3 |
Merge origin/main into release/v0.8.0
PR #2461 sync prep — resolves 14 conflicts merging 84 main-side commits on top of 58 release-side commits accumulated during the 0.8.0 cycle. Resolution summary: Take main (theirs) where main carried deliberate forward progress: - apps/web/src/components/PluginCard.tsx — 7 hunks, i18n migration: hardcoded English aria-labels/titles replaced with t() calls keyed on pluginCard.* (all 8 keys verified present in en.ts). - apps/web/src/components/TasksView.tsx — 1 hunk, source-ingestion feature: sortedRoutines (newest-first), sourceIngestionTemplates, patchSourceForm, submitSourceIngestion. activeCount/pausedCount semantics preserved (now keyed on sortedRoutines, count unchanged). - e2e/ui/app.test.ts — new node:fs/promises + tmpdir + path + @/timeouts imports needed by main-side test helpers. - e2e/ui/settings-local-cli-codex-fallback.test.ts — menu-dismissal helper block added by main. Keep both sides where each added a different field to the same object literal: - apps/web/src/components/ProjectView.tsx (locale + analyticsHints spread). - apps/web/src/components/DesignSystemFlow.tsx (locale + analyticsHints). Take release (ours) where release carried deliberate work that ships 0.8.0: - CHANGELOG.md — release-side 0.8.0 entry + PR link refs; main's Unreleased section was the same body of work, now finalized. - apps/landing-page/public/{apple-touch-icon,favicon}.png + apps/web/public/app-icon.svg — release-side visual refresh assets consistent with 0.8.0 stable ship. - tools/pack/src/linux.ts — packageVersion const required by line 466; taking main's empty line would build-error. - e2e/ui/project-management-flows.test.ts + e2e/ui/settings-api-protocol.test.ts + e2e/ui/settings-memory-routines.test.ts — release-side release-smoke hardening (shangxinyu1 + PerishFire) takes precedence on overlap. Closes-issue / unblocks: PR #2461 sync release/v0.8.0 → main. |
||
|
|
10e11531a1 |
Improve deck home previews and plugin gallery performance (#2698)
Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
e6da01e998 | Add i18n metadata for official content (#2692) | ||
|
|
0ba88a064d |
Add Codex interactive capability map example (#2657)
* Add Codex interactive capability map example * Fix Codex map preview entry --------- Co-authored-by: tuolaji <tuola@tuolajideMacBook-Air.local> |
||
|
|
bddec2391d | Fix Simple Deck discovery form contract (#2602) | ||
|
|
ce95266586 |
[codex] Polish home composer working-directory controls (#2468)
* Polish design system home flows * Polish home prompt presets * Polish home working directory controls * test: align home hero chrome smoke * fix: stabilize home composer ci checks --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
c80acfefeb |
fix(daemon,web): block pitch-deck placeholder publishes and unbreak framework decks (#2384)
Two preview-time bugs surfaced ahead of 0.8.0: 1. Pitch-deck example (#2215): the official html-ppt-pitch-deck prompt asked the agent to confirm three facts first, but the manifest had no structured `od.inputs`, so the platform's required-input gate had no fields to enforce and the run could publish HTML that still contained unresolved fundraising placeholders (`Name to confirm`, `$X.XM`, `Replace this panel with`, ...). Add structured required inputs to the manifest and a daemon-side publication guard that rejects HTML/deck artifact writes whose body still contains those placeholders. Scope is the file-write boundary only (no assistant-text scanning), so the guard cannot trip on the agent's chat prose mid-clarification. 2. Framework deck preview off-screen: `injectDeckBridge` injected `place-content: center !important` on `.deck-shell` for every deck-mode srcdoc, which forced the framework's `display: grid` shell to re-center its implicit track. The framework's `fit()` already centers a `transform-origin: top left` stage with an explicit `translate(tx, ty)` that assumes the stage's natural layout position is (0, 0); the two centerings stacked and the scaled stage landed ~1000px off-screen, so the preview showed a sliver of slide content in the top-left with the rest black. Skip the override when the framework's `id="deck-stage"` marker is in the doc, and drop the dead `display: grid; place-items: center` from the deck framework template so future drift can't re-introduce the same stack. |
||
|
|
f1870cbf3d |
chore(featured): curate Featured picks down to top 10 across categories (#1966)
* chore(featured): curate Featured picks down to top 10 across categories
The picker's Featured chip currently surfaces 64 plugins because
`isFeaturedPlugin` (apps/web/src/components/plugins-home/facets.ts)
treats any finite `od.featured` number as featured, and the field
had been adopted incrementally by 51 skills + 13 templates without
a curation step. The result is a "Featured" tab that's effectively
"everything tagged at all" — no editorial signal.
Curate down to 10 picks, allocated to keep the showcase legible:
0.001 skills/deck-swiss-international
0.01 skills/deck-guizang-editorial
0.02 design-templates/magazine-poster [add]
0.04 skills/doc-kami-parchment
0.10 design-templates/web-prototype-taste-brutalist [add od: block]
0.13 skills/video-hyperframes
0.14 skills/frame-glitch-title
0.15 skills/vfx-text-cursor
0.16 skills/frame-logo-outro
0.17 skills/deck-open-slide-canvas
Selection mirrors the html-anything `recommended: 1..10` ranking
(html-anything is the upstream content source for these skills, per
the `od.upstream` field on each SKILL.md). Two of those 10 picks
weren't in the prior featured set at all — `magazine-poster` had no
`od.featured` field and `web-prototype-taste-brutalist` had no `od:`
block at all — so they get added rather than just rebalanced.
Removes `od.featured` from the other 56 files. No UI code change;
the existing `isFeaturedPlugin` logic now reads a curated set
instead of an accidental one.
* chore(featured): align baked plugin manifests with curated top 10
The picker reads `od.featured` from each plugin's
`plugins/_official/examples/<id>/open-design.json` manifest, not from
the SKILL.md frontmatter the previous commit edited. Without this
follow-up the curated set of 10 would be invisible to users — the
picker's Featured chip would still surface 27 baked plugins from the
pre-existing manifests.
Mirror the SKILL.md curation into the baked layer:
removed `od.featured` from 19 manifests:
article-magazine, card-xiaohongshu, data-report,
frame-data-chart-nyt, frame-flowchart-sticky,
frame-light-leak-cinema, frame-liquid-bg-hero,
frame-macos-notification, guizang-ppt, html-ppt,
kami-deck, kami-landing, mockup-device-3d,
open-design-landing-deck, ppt-keynote, resume-modern,
social-reddit-card, social-spotify-card, social-x-post-card
added `od.featured` to 2 manifests:
magazine-poster -> 0.02
web-prototype-taste-brutalist -> 0.10
Verified locally against `daemon /api/plugins`: featured count is
now exactly 10, matching the SKILL.md source of truth from the
previous commit.
|
||
|
|
9ea33e076b |
feat(context-plugins): add support for context plugins in project metadata and UI
- Introduced a new `contextPlugins` field in the `ProjectMetadata` type to accommodate plugins selected via `@` mentions, allowing for additive context in project creation. - Updated the `HomeHero` and `EntryShell` components to handle and display context plugins, enhancing user interaction with selected plugins. - Implemented rendering logic for context plugins in the metadata block, providing clear visibility of selected plugins and their descriptions. - Enhanced the UI to support the removal of context plugins and display additional details on hover, improving the overall user experience. This update significantly enriches the project creation process by allowing users to incorporate multiple context plugins seamlessly. |
||
|
|
0edbf38171 |
feat(plugins): add specVersion and version fields to plugin and marketplace schemas
- Introduced `specVersion` and `version` fields to the plugin and marketplace schemas, ensuring better versioning and compatibility tracking. - Updated various components and functions to handle the new fields, including database migrations, plugin snapshots, and marketplace management. - Enhanced tests to validate the presence and correctness of the new fields in plugin manifests and marketplace entries. - Improved documentation to reflect the changes in schema requirements and provide guidance on the new versioning system. This update strengthens the plugin ecosystem by providing clear versioning, enhancing the reliability and maintainability of plugins and marketplaces. |
||
|
|
d3d95121f3 |
feat(plugins): enhance visual score sorting and add new example templates
- Updated the `sortByVisualAppeal` function to prioritize featured ranks, ensuring that curated plugins are displayed prominently. - Added tests to verify the new sorting logic, ensuring that plugins with numeric featured ranks are sorted correctly ahead of others. - Introduced new example templates for a magazine article layout, a Twitter share card, and a Xiaohongshu card, expanding the available options for users. - Enhanced the overall plugin preview experience by integrating these new templates, providing users with more visually appealing and functional examples. This update significantly improves the plugin sorting mechanism and enriches the template offerings, enhancing user engagement and experience. |
||
|
|
8b2d48a258 |
feat(daemon, web): enhance plugin preview handling and add new templates
- Introduced logic to assemble example slides with a companion template when the declared entry is missing, improving the user experience for plugin previews. - Updated the server logic to handle special cases for `example-slides.html`, ensuring proper fallback to `template.html` when applicable. - Enhanced tests to verify the new preview assembly functionality and ensure correct rendering of fallback content. - Added new HTML and Markdown examples for various skills, including a magazine article layout and a Twitter share card, expanding the available templates for users. This update significantly improves the plugin preview experience, providing users with more robust and visually appealing fallback options. |
||
|
|
9e196d34af |
feat(daemon, web): enhance plugin sharing workflows and UI components
- Updated the plugin sharing prompts to utilize local daemon endpoints for publishing to GitHub and contributing to Open Design, streamlining the user experience. - Refactored the `PluginsView` and `PluginShareMenu` components to support new sharing functionalities, including confirmation modals and improved link handling. - Enhanced the CSS styles for the plugin share confirmation modal and related UI elements for better visual consistency. - Added tests to verify the functionality of the new sharing workflows and ensure proper integration within the existing plugin management system. This update significantly improves the plugin sharing experience, making it easier for users to publish and contribute their plugins effectively. |
||
|
|
c36609c47d |
feat(daemon, web): implement plugin sharing project creation and enhance CLI functionality
- Added new flags for conversation, message, agent, and model in the CLI to support enhanced plugin sharing features. - Introduced a new API endpoint for creating share projects for plugins, allowing users to publish to GitHub or contribute to Open Design. - Updated the UI components to facilitate the new sharing functionalities, including prompts for user input during the sharing process. - Enhanced the project management system to handle new plugin share actions, improving user interaction and experience. - Added tests to ensure the reliability of the new sharing features and their integration within the existing plugin management system. This update significantly enhances the plugin ecosystem by enabling users to share their creations more effectively and streamline collaboration. |
||
|
|
13d5598b0c |
feat(web, daemon): enhance plugin import functionality and UI components
- Added support for uploading plugins via zip files and folders, improving the plugin import process. - Introduced a new `PluginImportModal` for a streamlined user experience when importing plugins. - Updated the `PluginsView` to include disabled states for unfinished plugin areas, enhancing clarity for users. - Refactored various components to utilize the new `resolvePluginQueryFallback` function for improved localization handling. - Enhanced CSS styles for better visual feedback and responsiveness in the plugin import interface. This update significantly improves the plugin management experience, making it easier for users to import and manage plugins effectively. |
||
|
|
443aea72c5 |
feat(daemon, web): enhance plugin handling and UI integration
- Introduced a new plugin upload mechanism with file size limits and memory storage, allowing users to upload plugins directly. - Implemented fallback logic for plugin application, ensuring projects can be created without explicit plugin requests. - Enhanced the UI to support plugin selection and integration, including a new `PluginsView` component for managing plugins. - Updated various components to utilize localized text for plugin queries, improving user experience across different languages. - Added tests for new plugin functionalities and local skill loading, ensuring reliability and correctness. This update significantly improves the plugin management experience, providing users with better tools for plugin integration and interaction. |
||
|
|
c12c816a44 |
feat(design-systems): add new design systems for Agentic, Airtable, Ant, Apple, Application, Arc, and Artistic
- Introduced comprehensive design documentation and JSON configurations for multiple design systems, including Agentic, Airtable, Ant, Apple, Application, Arc, and Artistic. - Each design system includes detailed guidelines on visual themes, color palettes, typography, spacing, layout, components, and interaction principles. - Enhanced the overall design framework to support diverse user interfaces and improve consistency across applications. This update significantly enriches the design resources available for developers, enabling them to create visually cohesive and user-friendly applications. |
||
|
|
5af84c09af |
feat(web): refactor PluginsHomeSection to use tag-based filtering and introduce PluginCard component
- Replaced the legacy tabbed categorization in `PluginsHomeSection` with a tag-driven approach, allowing dynamic filtering based on plugin tags. - Introduced a new `PluginCard` component to encapsulate the rendering of individual plugin cards, improving separation of concerns and maintainability. - Added a `usePluginCategories` hook to manage plugin visibility and filtering logic, enhancing the overall structure and testability of the component. - Implemented a "More" pill for overflow tags in the filter row, improving user interaction with a cleaner UI. - Updated CSS styles to support the new layout and improve visual consistency across the plugins home section. This update significantly enhances the user experience by providing a more flexible and intuitive way to discover and interact with plugins. |