ManyvereConsole

Voor ontwikkelaars

Novi Module Protocol 2026-06-10.

Deze pagina is gebaseerd op de interne bron MODULE_PROTOCOL.md en vat de build-then-couple workflow samen voor externe modulemakers.

Module anatomy

Elke feature leeft in een eigen SwiftPM-target onder tools/native-app/Sources/FeatureX/. Een module mag afhangen van kernelpakketten zoals NoviNativeCore,NoviNativeDesignSystem, NoviNativeAPI,NoviNativeSync en NoviNativeModuleKit. Een feature target importeert geen NoviNativeFeaturesen hangt niet zomaar af van andere feature targets.

  • FeatureXView.swift
  • FeatureXClient.swift
  • FeatureXViewModel.swift
  • XModule.swift
  • Tests voor view model, descriptor en niet-triviale modulelogica

Descriptor contract

NoviModuleDescriptor is het enige shell-facing contract. De catalogus bezit canonieke label-, icoon-, slug- en categoriedata; concrete descriptors voegen root views, sidebar items en v2 metadata toe.

public enum XModule: NoviModule {
    public static var descriptor: NoviModuleDescriptor {
        NoviModuleDescriptor(
            id: "x-registry-id",
            version: "1.0.0",
            author: "Manyvere",
            minHostVersion: noviModuleProtocolVersion,
            permissions: [],
            topLevelId: "module-N",
            topLevelSlug: "x",
            displayName: "X",
            menuLabel: "X",
            systemImage: "square.grid.2x2",
            architectureNodeId: "modules.x",
            extraArchitectureNodeIds: [],
            category: .other,
            makeRootView: { context in
                AnyView(
                    FeatureXView(
                        config: context.config,
                        selectedSidebarItemID: context.selectedSidebarItemID,
                        onSelectSidebarItem: context.onSelectSidebarItem
                    )
                )
            },
            sidebarItems: [
                NoviModuleSidebarItem(
                    id: "overview",
                    label: "Overview",
                    systemImage: "square.grid.2x2"
                ),
            ],
            isTopLevelSidebarEntry: false
        )
    }
}
VeldRol
idUnieke registry-id. Moet overeenkomen met docs/module-index.json.
versionImplementatieversie van de module, standaard 1.0.0.
authorPersoon of organisatie achter de module, standaard Manyvere.
permissionsVerklaarde permissies. In protocol v2 documenterend, nog niet door de host afgedwongen.
minHostVersionMinimaal ondersteunde host/protocolversie, meestal noviModuleProtocolVersion.
makeRootViewRoot view factory voor renderbare modules.
sidebarItemsSubnavigatie-items die de shell kan selecteren en terugkoppelen.

Build-then-couple workflow

  1. Kopieer Sources/FeatureTemplate naar Sources/FeatureX.
  2. Hernoem types, bestanden, accessibility identifiers en tests.
  3. Voeg de library product, target en test target toe in Package.swift.
  4. Werk docs/module-index.json en docs/menu-readiness.json bij.
  5. Genereer de native catalogus opnieuw en vervang placeholder ids.
  6. Registreer de descriptor in NoviFeatureModuleBootstrap.
  7. Draai de verificatiepoorten.
# From the repository root
node scripts/gen-native-module-catalog.mjs

# Then verify from tools/native-app
swift test

# Then run the repository checks
npm run check

Coupling

Registratie is single-threaded via de module registry. Voor een bestaande sidebarsectie match je op catalogus-id; voor een nieuwe top-level entry zet je isTopLevelSidebarEntry op true, voeg je readiness metadata toe en laat je de registry de sidebar aansturen.

NoviModuleRegistry.shared.register(XModule.descriptor)

Verification gates

  • Descriptor-id bestaat in docs/module-index.json.
  • Readiness-id bestaat wanneer de module in menu of sidebar staat.
  • makeRootView gebruikt NoviModuleRootViewContext.
  • Sub-sidebar modules koppelen selectedSidebarItemID en onSelectSidebarItem.
  • Elke macOS sheet gebruikt .noviDismissibleSheet().
  • Tests dekken descriptor metadata en view-model gedrag.
  • swift test, npm run check en de mac build/launch gate slagen.