ADR-0019: Desk Navigation Shell Ergonomics and Command Palette
- Status: Implemented
- Date: 2026-10-12
Context
Framework M's web client (libs/framework-m-desk) provides the unified administrative shell and desktop experience across business applications (Finance, POS, WMS, CRM). As the multi-app footprint expands, users experienced navigational ambiguity:
- Unscoped routes and hardcoded paths: Several navigation components assumed a fixed
/appworkspace root, creating broken links when running in modular workspace contexts (such as/finance,/pos, or/wms). - Settings sprawl: System configuration was scattered across fragmented DocType list views with no central entry point or app-specific settings discovery.
- Command Palette usability: The command palette lacked fuzzy search indexing, WAI-ARIA combobox state adherence, and pluggable extension points for applications or AI assistant integrations.
- OAuth post-login redirection: Initiating OAuth flows from deep links frequently dropped the target destination (
?to=or?redirect=), while naive forwarding posed an open-redirect vulnerability.
Decision
We formalized the navigation ergonomics and command palette architecture across @framework-m/desk and backend adapter layers:
1. Dynamic Workspace Prefix Scoping
- All navigation components (
PrimaryRail,SettingsOverviewPage, and contextual drawer links) dynamically extract and respect the active workspace prefix from the route path (/${workspacePrefix}/...). - Global entry points (such as
DefaultLandingPageat root/) provide customizableworkspacePrefixprops with safe fallbacks to standard workspaces.
2. Centralized Settings Hub (SettingsOverviewPage)
- Implemented
SettingsOverviewPageto aggregate core system administration cards (Users, Roles, Custom Permissions, System Settings) and dynamically discovered plugin settings singletons. - Extended
ResourceRegistrationwith explicit metadata flags (isSettings?: boolean,category?: string), allowing apps to explicitly register their configuration views in the hub while retaining a fallback heuristic for resources containing "settings".
3. Accessible, Fuzzy-Indexed Command Palette
- Integrated Lucide icon normalization and WAI-ARIA combobox accessibility guidelines (dynamic
aria-expandedand cleanaria-activedescendanthandling). - Command registration via
registerCommand()in the plugin registry enables applications and future AI assistant sidecars to inject commands and intent triggers directly intoCmd+K/Ctrl+K.
4. Open-Redirect-Protected OAuth State Forwarding
- Updated the backend
OAuthStateManagerto capture query destination parameters (?to=/?redirect=) during/auth/oauth/{provider}/start. - Added strict
sanitize_relative_path()validation: only clean, same-origin relative paths are accepted (rejecting schemes, protocol-relative//origins, and backslashes\), eliminating open redirect exploits upon post-login return.
Consequences
Positive
- Consistent multi-app UX: Seamless navigation across diverse prefixes (
/finance/*,/pos/*,/wms/*,/app/*). - Extensibility: Third-party plugins and AI assistants can contribute first-class actions and settings cards without modifying core shell code.
- Security: Hardened post-login redirection with zero open redirect exposure.
Negative
- Plugin resource manifests must adhere to registration schemas for optimal categorization.