# 20_UI_SHELL_FRONTEND_RUNTIME.md # DevOS UI Shell / Frontend Runtime > DevOS 前端不是一个普通 Admin Dashboard。 > > 它应该是一个可扩展的 **Application UI Shell + Resource UI Runtime + Plugin UI Runtime + Agent UI Runtime**。 > > Plugin、MCP、Agent、Task、Resource、Action、Workflow 都必须能够以统一方式进入 DevOS UI,而不能各自重新实现 Layout、Router、Permission、Menu、Settings、Table、Detail、Form、Task、Notification、Realtime 等基础设施。 --- # 1. 目标 DevOS UI Runtime 必须解决以下问题: ```text 一个 DevOS ↓ 多个 Plugin ↓ 多个 Resource ↓ 多个 Action ↓ 多个 Agent / Skill ↓ 多个 Task / Workflow / MCP ``` 最终用户看到的应该仍然是: ```text ┌─────────────────────────────────────────────────────┐ │ DevOS │ ├───────────────┬─────────────────────────────────────┤ │ Navigation │ Main Content │ │ │ │ │ Dashboard │ Resource / Task / Agent / Plugin │ │ Projects │ │ │ Resources │ │ │ Tasks │ │ │ Agents │ │ │ Plugins │ │ │ Settings │ │ └───────────────┴─────────────────────────────────────┘ ``` 而不是: ```text Plugin A └── 自己的 Layout └── 自己的 Router └── 自己的 Permission Plugin B └── 自己的 Layout └── 自己的 Router └── 自己的 Permission ``` DevOS 必须提供统一: - App Shell - Router - Navigation - Permission - Resource UI - Action UI - Table - Form - Detail - Search - Filter - Task UI - Agent UI - Plugin UI - Settings - Notification - Realtime - Modal / Drawer - Command Palette - Global Search - Breadcrumb - Page State - Error Boundary - Loading - Empty State - Responsive - Theme - i18n --- # 2. 核心原则 ## 2.1 UI 不拥有业务逻辑 禁止: ```text React Component ↓ 直接调用数据库 ``` 禁止: ```text React Component ↓ 直接调用第三方 API ``` 禁止: ```text Plugin Page ↓ 自己实现权限 ``` 正确: ```text UI ↓ Query / Action ↓ API ↓ DevOS Runtime ↓ Resource / Action Runtime ``` --- # 3. UI 总体架构 ```text DevOS UI │ ▼ ┌────────────┐ │ UI Shell │ └─────┬──────┘ │ ┌───────────────┼────────────────┐ ▼ ▼ ▼ Navigation Router Global UI │ │ │ ▼ ▼ ▼ Menu Registry Route Registry Search / Cmd │ │ └───────────────┼────────────────┐ ▼ ▼ Resource UI Plugin UI │ │ ▼ ▼ Action UI Agent UI │ │ └───────┬────────┘ ▼ API / Runtime ``` --- # 4. Frontend Package Architecture 推荐: ```text packages/ ├── ui/ ├── ui-shell/ ├── ui-router/ ├── ui-navigation/ ├── ui-resource/ ├── ui-action/ ├── ui-form/ ├── ui-table/ ├── ui-detail/ ├── ui-search/ ├── ui-task/ ├── ui-agent/ ├── ui-plugin/ ├── ui-settings/ ├── ui-notification/ ├── ui-realtime/ ├── ui-command/ ├── ui-theme/ ├── ui-i18n/ └── frontend-runtime/ ``` 应用: ```text apps/ └── web/ ├── src/ │ ├── bootstrap/ │ ├── app/ │ ├── routes/ │ ├── providers/ │ └── main.tsx └── package.json ``` Plugin: ```text plugins/ ├── seo/ │ └── ui/ ├── devops/ │ └── ui/ └── crm/ └── ui/ ``` --- # 5. UI Runtime 核心 Runtime: ```ts export interface UIRuntime { registerRoute(route: UIRoute): void registerNavigation(item: NavigationItem): void registerResource(resource: ResourceUI): void registerAction(action: ActionUI): void registerWidget(widget: UIWidget): void registerPage(page: UIPage): void registerCommand(command: UICommand): void registerSettings(settings: SettingsDefinition): void resolveRoute(path: string): UIRoute | undefined resolveNavigation(): NavigationItem[] canRender(target: UIVisibilityContext): Promise } ``` --- # 6. UI Context 所有页面都应该拥有统一 Context: ```ts export interface UIContext { user: UserContext organization?: OrganizationContext project?: ProjectContext environment?: EnvironmentContext permissions: PermissionSet locale: string timezone: string theme: ThemeMode featureFlags: FeatureFlagSet } ``` 页面不得自行重新获取: ```text currentUser currentOrganization permissions environment theme locale ``` 应该统一由 UI Runtime 提供。 --- # 7. Application Shell Shell 是 DevOS 的最外层 UI。 ```tsx ``` --- # 8. Shell Layout 建议: ```text ┌──────────────────────────────────────────────────────┐ │ Logo Global Search Command User │ ├────────────┬─────────────────────────────────────────┤ │ │ Breadcrumb │ │ Navigation ├─────────────────────────────────────────┤ │ │ │ │ Dashboard │ Page │ │ Projects │ │ │ Resources │ │ │ Tasks │ │ │ Agents │ │ │ Plugins │ │ │ │ │ │ Settings │ │ └────────────┴─────────────────────────────────────────┘ ``` 支持: - sidebar collapse - mobile drawer - top navigation - nested navigation - workspace navigation - project navigation - plugin navigation --- # 9. Navigation Runtime Plugin 不应该修改主 Layout。 Plugin 只注册 Navigation: ```ts export interface NavigationItem { id: string label: string icon?: string path?: string parentId?: string order?: number permission?: PermissionRequirement featureFlag?: string badge?: NavigationBadge children?: NavigationItem[] } ``` 例如 SEO Plugin: ```ts { id: "seo.websites", label: "Websites", path: "/seo/websites", parentId: "seo", permission: { action: "seo.website.read" } } ``` --- # 10. Navigation 不等于 Permission Navigation: ```text 用户可以看到什么 ``` Permission: ```text 用户可以做什么 ``` 因此: ```text Navigation Filter ↓ Permission Filter ↓ Scope Filter ↓ Visible Navigation ``` 但: > UI 隐藏按钮不能代替后端授权。 --- # 11. Router Runtime 使用: ```text React Router ``` 统一 Route Registry: ```ts export interface UIRoute { id: string path: string component: React.ComponentType parentId?: string layout?: string permission?: PermissionRequirement metadata?: RouteMetadata } ``` --- # 12. Plugin Route Plugin 可以注册: ```ts plugin.registerRoute({ id: "seo.website.list", path: "/seo/websites", component: WebsiteListPage, permission: { action: "seo.website.read" } }) ``` 但 Plugin 不允许: ```ts createBrowserRouter(...) ``` Plugin 不允许重新创建: ```text Router Shell Auth Permission Theme Notification ``` --- # 13. Route Metadata ```ts export interface RouteMetadata { title?: string icon?: string breadcrumb?: BreadcrumbDefinition keepAlive?: boolean fullscreen?: boolean searchable?: boolean commands?: string[] featureFlag?: string } ``` --- # 14. Resource UI Runtime 这是 DevOS UI 的核心。 Resource 定义: ```text Resource ├── Schema ├── Actions ├── Permissions ├── Relations └── UI Definition ``` 因此 Resource 可以自动生成: ```text List Detail Create Edit Delete Bulk Actions Search Filter Sort Relation Timeline Activity ``` --- # 15. Resource UI Definition ```ts export interface ResourceUI { resource: string label: string icon?: string list?: ResourceListDefinition detail?: ResourceDetailDefinition form?: ResourceFormDefinition search?: ResourceSearchDefinition actions?: string[] } ``` 例如: ```ts { resource: "seo.website", label: "Website