Skip to main content

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:

  1. Unscoped routes and hardcoded paths: Several navigation components assumed a fixed /app workspace root, creating broken links when running in modular workspace contexts (such as /finance, /pos, or /wms).
  2. Settings sprawl: System configuration was scattered across fragmented DocType list views with no central entry point or app-specific settings discovery.
  3. 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.
  4. 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 DefaultLandingPage at root /) provide customizable workspacePrefix props with safe fallbacks to standard workspaces.

2. Centralized Settings Hub (SettingsOverviewPage)​

  • Implemented SettingsOverviewPage to aggregate core system administration cards (Users, Roles, Custom Permissions, System Settings) and dynamically discovered plugin settings singletons.
  • Extended ResourceRegistration with 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-expanded and clean aria-activedescendant handling).
  • Command registration via registerCommand() in the plugin registry enables applications and future AI assistant sidecars to inject commands and intent triggers directly into Cmd+K / Ctrl+K.

4. Open-Redirect-Protected OAuth State Forwarding​

  • Updated the backend OAuthStateManager to 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.