Give the application a familiar frame Mechanism
The shell is the frame people use throughout the application: its navigation, search, workspace controls and notifications. Wildo supplies these surfaces and their behavior; you choose which appear and where they belong.
Modules contribute their own destinations to that shared frame. A new part of the product can become discoverable through the sidebar or command palette without creating another navigation system.
Example: Find work from anywhere
A task application keeps its lists in the sidebar, a search trigger in the top bar and notifications beside the user menu. The task module contributes its commands; both navigation surfaces lead into the same resource operations.

For engineers
appComponentsConfiguration chooses the shell surfaces. hostedComponents places a supported control in a menubar or sidebar; enabling a control and providing its host are distinct decisions. Wonder Todos places the command-menu trigger in both, while the shared interaction owner maintains one palette and keyboard registration.
The task module’s actual command declarations are below. Imports are omitted; LauncherItemTargetKind is from @wildo-ai/saas-frontend-lib/companion, and the resource identifiers belong to the application.
export const moduleCommandMenuItems: CommandMenuCommand[] = [
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.TODOS,
operation: CoreResourceOperation.CREATE,
category: 'actions',
},
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.TASKS,
operation: CoreResourceOperation.CREATE,
category: 'actions',
},
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.TODOS,
operation: CoreResourceOperation.LIST,
category: 'navigation',
},
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.TASKS,
operation: CoreResourceOperation.LIST,
category: 'navigation',
},
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.TODO_LISTS,
operation: CoreResourceOperation.LIST,
category: 'navigation',
searchKeywords: ['boards'],
},
{
kind: LauncherItemTargetKind.RESOURCE_OPERATION,
resourceType: TasksManager_ResourceType.DRAFT_NOTES,
operation: CoreResourceOperation.LIST,
category: 'navigation',
searchKeywords: ['scratch'],
},
];
The resource target carries the operation’s identity, not a hand-written URL. resolveCommandMenuCommands in launcher-resolution.ts resolves it using the active scope. Runtime-capability filtering omits unavailable declarations before resolution; feature and access checks remain separate decisions. Showing a command never grants permission to execute its operation.
Give the command a visible host
A module command needs the command menu enabled and a trigger placed in the shell. This illustrative excerpt keeps those two decisions together; merge it with the application’s existing shell configuration rather than replacing its other controls.
[ApplicationLevelComponentType.COMMAND_MENU]: {
policy: CommandBarPolicy.OMNIBOX,
showRecent: true,
maxRecentItems: 5,
showShortcuts: true,
openShortcut: 'Mod+K',
},
[ApplicationLevelComponentType.MENUBAR]: {
displayPolicy: 'FIXED',
hostedComponents: [{
componentType: ApplicationLevelComponentType.COMMAND_MENU,
placement: HorizontalPlacement.END,
}],
items: [],
},
Use the public companion shell vocabulary and HorizontalPlacement from @wildo-ai/presets-components-models. Once the module’s commandMenuItems reaches the registry below, this host opens the shared palette containing the resolved commands. The keyboard shortcut and visible trigger reach the same menu. A declared target still needs its resource operation registered and available in the current scope.
Register the contribution in the application
The module exports sidebarSections, quickSwitcherFields and commandMenuItems together as ShellModuleContributions. Its FrontendModule spreads that contribution beside its resource UI behavior. Wonder Todos then passes the aggregated module registry through this selected provider-options block:
frontendConfigOverrides: buildFrontendModuleConfigOverrides({
navigationLayout: navigationLayoutConfig,
designSystemConfiguration: frontendResolvedDesignSystemConfiguration,
baseAppComponentsConfiguration: appShellConfig,
moduleRegistry: frontendModuleRegistry,
homeDefinition: homeDefinitionFactory(),
errorPageConfig,
}),
baseAppComponentsConfiguration supplies the global frame; moduleRegistry supplies the module-owned additions. Keep each destination in one owning contribution so the same launcher is not rendered twice. Labels, icons and operation definitions should come from their established application sources.
Choose the surfaces that serve the product
A sidebar can collapse into a burger menu at a declared breakpoint. A command menu can combine static commands and resource searches when those resources expose the required search operations. Status, utility and activity surfaces should be enabled only with useful content: an activity rail needs application modes, and a quick switcher needs scope fields.
To replace a shell component’s rendering, use its registered component seam and behavior hook. Keep navigation through the launcher/controller contracts so custom presentation retains scope-aware routes and shared interactions.



















