Files
freedak f7a720204a Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用
- 添加所有子项目的完整源代码
- 保留原始 .git 为 .git.bak 备份
2026-07-04 19:20:46 +08:00

3.8 KiB

Frontend

The frontend is a single React 19 SPA in ui/. The Tauri desktop shell and the nomifun-web host load the same Vite build from ui/dist; the renderer talks to the backend through HTTP and WebSocket, with a small Tauri adapter only for desktop shell operations.

Stack

Concern Current choice
Framework React 19 + TypeScript
Bundler Vite 6
Routing react-router-dom v7 with HashRouter
UI Arco Design + custom CSS theme layers + UnoCSS
Data SWR plus React contexts for app-shaped state
i18n i18next / react-i18next; current app locales are zh-CN and en-US
Terminal xterm.js with fit/web-links/webgl addons
Markdown react-markdown, GFM, KaTeX, Mermaid

Source Layout

ui/src/
├── common/       bridge/API/types/util code shared across hosts
├── platform/     small substrate for storage/logger/theme/runtime bridge
└── renderer/     React app: pages, layout, hooks, services, styles

The renderer imports the composite bridge from ui/src/common/adapter/ipcBridge.ts. Most product operations are HTTP calls. Tauri-specific operations are guarded behind isTauri() and implemented in the adapter layer rather than scattered through pages.

Backend URL And Trust

Desktop:

  • apps/desktop/src/main.rs injects window.__backendPort.
  • It also injects a per-boot window.__nomiLocalTrust secret.
  • The init script patches fetch and XMLHttpRequest so requests to the embedded loopback backend include x-nomi-local-trust.

Web:

  • No port is injected.
  • The bridge uses same-origin /api and /ws.
  • Authenticated web mode uses the session cookie plus CSRF double-submit header.

Current Route Map

The source of truth is ui/src/renderer/components/layout/Router.tsx.

Route Surface
/login Login / first-run setup.
/companion Desktop companion window route; outside the normal protected app layout.
/guid Session start surface.
/conversation/:id Conversation runtime.
/terminal-new Terminal creation.
/terminal/:id Terminal runtime.
/models Model and agent management.
/assistants Assistant and skill hub.
/mcp MCP server management.
/open-capabilities Remote/public capability exposure.
/scheduled, /scheduled/:job_id Scheduled tasks.
/requirements, /requirements/extensions, /requirements/sources Requirements Platform, AutoWork, notification/source extensions.
/nomi Companion configuration.
/knowledge, /knowledge/:id Knowledge base list/detail.
/settings/system and related settings subroutes System settings page and sub-sections.

Legacy settings paths such as /settings/model, /settings/agent, /settings/capabilities, /settings/skills-hub, /settings/tools, /settings/webui, /settings/assistants, and /settings/webhook are redirects. Do not document them as primary navigation.

There is no current /team/:id frontend route. Backend team code may still exist, but the product route is not surfaced in the current router.

State And Data

  • SWR owns most remote list/detail state.
  • AuthProvider, theme, feedback, preview, and conversation-history contexts own app-shaped state.
  • configService initializes before i18n/theme consumers so early render reads backend-backed preferences.
  • Realtime events arrive through a singleton WebSocket and are demuxed by event name.

Desktop-Specific UX

Desktop shell behavior is implemented by Tauri commands and plugins:

  • updater check,
  • companion window reconciliation,
  • WebUI LAN listener status/start/stop,
  • keep-awake toggle,
  • tray label localization,
  • deep-link forwarding,
  • tray close behavior.

Browser builds no-op or degrade desktop-only affordances in the adapter layer.