Namespace Serenity.Hub.Infrastructure.Editor.Views
Classes
SerenityHubAdvancedView
Renders every catalog entry in Advanced as a tool card — the maintenance /
power-user catch-all (design ADR-4c: Validate/Project (JSON), every Docs/* entry, and the
other headless-CLI duplicates all live here, catalogued rather than dropped).
SerenityHubBrowseView
Renders every catalog entry in Browse as a tool card (spec §6).
SerenityHubCatalogGridBuilder
Shared rendering for a category-filtered grid of SerenityHubToolCards — Create, Browse, and Advanced differ only by which catalog category they render (spec §1: no view hardcodes its own tool list), so the filter + grid-building logic lives here once instead of being duplicated three times.
Since UX feedback round 4, the result is no longer one flat grid — entries are split into collapsible Foldout sections by SerenityHubCatalogGrouper so a 30+ item view stays scannable. SerenityHubValidateView groups into its own fixed Validators/Tools split instead, but reuses BuildSection(string, IReadOnlyList<VisualElement>) for the identical Foldout chrome.
SerenityHubCreateView
Renders every catalog entry in Create as a tool card (spec §1).
SerenityHubFinishSetupBanner
The "Finish setup" banner Home renders only when SerenityHubFinishSetupBannerPolicy finds an
erroring row (spec §3) — a distinct call-to-action separate from the metric card already showing that row's
own status, wrapping the exact same deep link so activating it opens the tool that would fix it. The whole
banner is clickable (UX feedback #4 — one interaction model, no per-card/per-banner button). Exposes
ActivateDeepLink() as a plain public method (mirrors SerenityHubMetricCard's
ActivateDeepLink) so it is testable without simulating a live UI Toolkit pointer event.
SerenityHubFinishSetupBannerPolicy
Pure decision logic for Home's "Finish setup" banner (spec §3): visible only when the row identified by
InstallationWiring or ProjectWiringHealth
is currently in an Error state — Required Unity Packages
deliberately does not trigger it. Kept separate from SerenityHubHomeView so the decision is
testable without constructing any VisualElement. Matches by Id —
a stable identifier shared with every row producer — rather than Title,
which is free-form presentation text a producer can reword without breaking this policy.
SerenityHubHomeView
The Hub's landing view (spec §3): status metric cards, a "Finish setup" banner shown only on an error state, a recents row, and a favorites row. Never triggers a synchronous full-project scan itself — it renders whatever BuildRows() currently returns.
Since Slice 6.4, SerenityHubStatus.BuildRows no longer calls
SerenityProjectValidationRunner.RunAll synchronously — its wiring-health row reads
SerenityHubValidationCache instead, rendering a "not yet run" state when nothing is cached. Opening
Home is therefore fully spec-compliant: no view triggers a synchronous full-project scan on open.
SerenityHubLearnView
Curated documentation view (spec §7, design ADR-9), rendered as three card sections (visual-coherence pass) instead of hand-built rows so it matches every other catalog-driven view: "Guides" (Designer Quickstart, Sample Scene Guide, the Cookbooks folder), "Tools" (the AI Agent Skills installer, looked up as a catalog entry and launched the same way any tool card is), and "Reference" (a link to the generated DocFX site that degrades gracefully — never throws, never silently no-ops — when the site has not been built yet).
SerenityHubValidateView
Renders every catalog entry in Validate as either a report card
(non-null ValidatorKind) or an open-tool card (null ValidatorKind), plus the Catalog
Staleness report card — the one Validate card with no backing catalog entry at all (design ADR-4c: it has
no real [MenuItem]/window of its own, so it is wired directly here instead of through the catalog).
Opening this view never runs a validator — cards render whatever is already cached (spec §5).
Since UX feedback round 4, the two card kinds render as two Foldout sections — "Validators" (report cards) first, then "Tools" (open-tool cards) — instead of one flat interleaved grid, reusing BuildSection(string, IReadOnlyList<VisualElement>) for the same chrome the path-derived Create/Browse/Advanced sections use.
SerenityHubViewRegistry
Registration seam for a sidebar view whose assembly the Hub cannot reference (design ADR-1 — e.g. the
CreateGame editor assembly references this one, never the reverse). A registering assembly's own
[InitializeOnLoad] static constructor calls Register(string, Func<ISerenityHubView>) on every domain reload;
registration is idempotent per view id so that rerun never accumulates duplicate entries.
SerenityHubViewStyles
USS class names for view-level chrome (sections, banners, rows) — sibling to SerenityHubCardStyles, which owns card-level selectors. Kept in one place so Slice 6's stylesheet has a single, stable, already-diffable selector surface for the views too.
Interfaces
ISerenityHubView
Contract every Hub sidebar view implements (design ADR-9): a stable id for navigation/persistence, the root visual tree the window mounts into its content host, and an explicit refresh hook the window calls each time the view becomes active. One class per view — no shared base class, no god window.