调研时间: 2026/07/08 调研范围: /home/zs/Develop/TraceCubeSandbox/web/ 全量 React/TypeScript 源码 目的: 系统性梳理 WebUI (管理控制台) 的架构、处理流程与安全配置

每节都带文件位置证据,可以直接引用。


1. 概述

WebUI 是 CubeSandbox 的浏览器端管理控制台,基于 React 18 + TypeScript 构建,提供沙箱、模板、节点、API 密钥和集群可观测性的可视化界面。

属性
语言TypeScript (React 18)
构建工具Vite 6
路由react-router-dom v6
数据获取TanStack Query v5
样式Tailwind CSS v3 + HSL 变量
UI 组件Radix UI (shadcn 风格)
状态管理Zustand v5
国际化i18next
API 客户端openapi-typescript (生成类型)
Mock 工具MSW (Mock Service Worker)
开发端口5173
代理Vite proxy /cubeapi → 127.0.0.1:3000

核心职责:

  • 沙箱管理: 创建/查看/暂停/恢复/销毁
  • 模板管理: 查看/构建/删除/兼容性矩阵
  • 节点管理: 集群健康监控
  • API 密钥管理
  • AI Agent 实例 (AgentHub)
  • 系统设置 (主题/语言/集群信息/账户)
  • 可观测性 (预留给 Prometheus/Grafana)
  • 网络管理 (预留)

2. 架构

2.1 顶层目录结构

来源: web/ 目录遍历

web/
├── package.json                  # 项目配置 + 依赖
├── vite.config.ts                # Vite 配置 + proxy + 版本注入
├── tailwind.config.js            # Tailwind 主题 + 颜色
├── tsconfig.json                 # TypeScript 严格模式
├── postcss.config.js             # PostCSS 配置
├── index.html                    # HTML 入口
├── public/
│   ├── mockServiceWorker.js      # MSW Service Worker (dev mock)
│   └── assets/
│       ├── cube-logo.svg         # 应用 Logo
│       └── cube.svg              # 图标
├── src/
│   ├── main.tsx                  # 入口 (QueryClient + Router + ThemeProvider)
│   ├── vite-env.d.ts             # Vite 类型声明
│   ├── lib/
│   │   ├── api.ts                # fetch 封装 + ApiError 类型
│   │   ├── session.ts            # localStorage session 管理
│   │   ├── utils.ts              # 工具函数
│   │   ├── mockFlag.ts           # Mock 模式开关
│   │   ├── sandboxActionError.ts # 沙箱操作错误格式化
│   │   └── templateConfig.ts     # 模板配置工具
│   ├── api/
│   │   ├── client.ts             # 类型化 API 客户端 (命名空间)
│   │   └── generated/
│   │       └── schema.ts         # openapi-typescript 生成的类型
│   ├── hooks/
│   │   ├── useRuntimeConfig.ts   # 运行时配置 hook
│   │   ├── useControlPlaneVersion.ts  # 控制面版本 hook
│   │   └── useGlobalHotkeys.ts   # 全局快捷键 hook
│   ├── components/
│   │   ├── ui/                   # 通用 UI 组件 (button/card/input/badge/skeleton 等)
│   │   ├── layout/               # 布局组件 (未使用)
│   │   ├── AuthGuard.tsx         # 路由守卫
│   │   ├── AppShell.tsx          # 应用外壳 (Rail + TopBar + Outlet)
│   │   ├── Rail.tsx              # 侧边导航栏
│   │   ├── TopBar.tsx            # 顶部栏
│   │   ├── ThemeProvider.tsx     # 主题提供者
│   │   ├── ThemeToggle.tsx       # 主题切换
│   │   ├── LanguageSwitcher.tsx  # 语言切换
│   │   ├── CommandPalette.tsx    # 命令面板 (Cmd+K)
│   │   ├── SandboxActionErrorBanner.tsx  # 操作错误提示
│   │   └── agents/               # Agent 组件
│   ├── pages/                    # 页面组件
│   │   ├── Login.tsx             # 登录页
│   │   ├── Overview.tsx          # 概览页
│   │   ├── Sandboxes.tsx         # 沙箱列表
│   │   ├── SandboxNew.tsx        # 创建沙箱
│   │   ├── SandboxDetail.tsx     # 沙箱详情
│   │   ├── Templates.tsx         # 模板列表
│   │   ├── TemplateDetail.tsx    # 模板详情
│   │   ├── Nodes.tsx             # 节点列表
│   │   ├── NodeDetail.tsx        # 节点详情
│   │   ├── Versions.tsx          # 版本信息
│   │   ├── Keys.tsx              # API 密钥
│   │   ├── AgentHub.tsx          # AI Agent 管理
│   │   ├── Settings.tsx          # 系统设置
│   │   ├── Network.tsx           # 网络 (预留)
│   │   ├── Observability.tsx     # 可观测性 (预留)
│   │   ├── TemplateStore.tsx     # 模板商店
│   │   └── Placeholder.tsx       # 占位页
│   ├── store/                    # Zustand stores
│   │   ├── ui.ts                 # UI 状态 (命令面板)
│   │   └── theme.ts              # 主题状态 (light/dark/system)
│   ├── state/
│   │   └── agentStore.ts         # Agent 全局状态
│   ├── data/
│   │   ├── agents.ts             # Agent 数据定义
│   │   └── templateStore.ts      # 模板商店数据
│   ├── types/                    # TypeScript 类型
│   ├── i18n/                     # 国际化配置
│   │   ├── index.ts              # i18next 初始化
│   │   ├── resources.ts          # 资源映射
│   │   └── types.d.ts            # i18n 类型声明
│   ├── locales/                  # 翻译文件
│   │   ├── zh/                   # 中文
│   │   └── ...                   # 各模块翻译
│   ├── styles/
│   │   └── globals.css           # 全局样式 + HSL 变量 + 组件样式
│   └── mocks/                    # MSW Mock
│       ├── browser.ts            # MSW worker 初始化
│       ├── handlers/             # Mock handlers
│       └── fixtures/             # Mock 数据

2.2 页面路由

来源: web/src/main.tsx:49-72

/login          → LoginPage           (公开)
/               → OverviewPage        (受保护)
/sandboxes      → SandboxesPage       (受保护)
/sandboxes/new  → SandboxNewPage      (受保护)
/sandboxes/:sandboxID → SandboxDetailPage (受保护)
/templates      → TemplatesPage       (受保护)
/templates/:templateID → TemplateDetailPage (受保护)
/nodes          → NodesPage           (受保护)
/nodes/:nodeID  → NodeDetailPage      (受保护)
/versions       → VersionsPage        (受保护)
/keys           → KeysPage            (受保护)
/store          → TemplateStorePage   (受保护)
/agenthub       → AgentHubPage        (受保护)
/settings       → SettingsPage        (受保护)
/observability  → ObservabilityPage   (受保护/预留)
/network        → NetworkPage         (受保护/预留)
/*              → 重定向到 /           (通配)

所有受保护路由嵌套在 <AuthGuard> 组件内,未认证用户被重定向到 /login

2.3 数据流

User browser              WebUI (React)                  CubeAPI
  │                              │                          │
  │ 用户操作 (页面交互)           │                          │
  │ ────────────────────────────▶│                          │
  │                              │                          │
  │                              │ ① TanStack Query          │
  │                              │   - 自动缓存 + 重试      │
  │                              │   - staleTime: 2-60s     │
  │                              │   - refetchInterval: 5-30s│
  │                              │                          │
  │                              │ ② api/client.ts          │
  │                              │   - 命名空间 API 封装     │
  │                              │   - 调用 lib/api.ts       │
  │                              │                          │
  │                              │ ③ lib/api.ts             │
  │                              │   - BASE: /cubeapi/v1     │
  │                              │   - 注入 X-API-Key        │
  │                              │   - 注入 X-Session-Token  │
  │                              │   - 注入 Content-Type      │
  │                              │   - 异常封装 ApiError     │
  │                              │                          │
  │                              │ ④ Vite proxy (开发环境)   │
  │                              │   /cubeapi → localhost:3000│
  │                              │ ────────────────────────▶│
  │                              │ ◀────────────────────────│
  │                              │                          │
  │                              │ ⑤ Zustand store           │
  │                              │   - 全局状态管理           │
  │                              │   - theme.ts: 主题持久化   │
  │                              │   - ui.ts: 命令面板状态    │
  │                              │   - agentStore.ts: Agent   │
  │                              │                          │
  │                              │ ⑥ i18next                 │
  │                              │   - 浏览器语言检测         │
  │                              │   - localStorage 缓存      │
  │                              │                          │
  │ ◀───────────────────────────│                          │
  │ 渲染 UI                      │                          │

3. 处理流程

3.1 认证流程

来源: web/src/pages/Login.tsx:14-46, web/src/components/AuthGuard.tsx:17-54, web/src/lib/session.ts:7-40

LoginPage                     CubeAPI
  │                              │
  │ POST /cubeapi/v1/auth/login  │
  │ { "username", "password" }   │
  │ ────────────────────────────▶│
  │                              │
  │                              │ ① 密码验证 (argon2)
  │                              │ ② 生成 session token (uuid)
  │                              │ ③ TTL 24h
  │                              │
  │ ◀───────────────────────────│
  │ { token, username,           │
  │   expiresInSecs }            │
  │                              │
  │ ④ setSession(token, username)│
  │   localStorage:              │
  │   - cube.session (token)     │
  │   - cube.sessionUser (name)  │
  │   - cube.authStatus (allowed)│
  │                              │
  │ ⑤ 跳转到 redirectTo (或 /)   │

AuthGuard 守卫逻辑:

来源: web/src/components/AuthGuard.tsx:17-54

AuthGuard mount
  │
  ├── GET /cubeapi/v1/auth/session
  │   │
  │   ├── 响应: { authRequired: false, authenticated: false }
  │   │   → 放行 (无数据库/开放模式)
  │   │
  │   ├── 响应: { authRequired: true, authenticated: true }
  │   │   → 放行 (有效 session)
  │   │
  │   └── 响应: { authRequired: true, authenticated: false }
  │       → 重定向到 /login (session 过期/无效)
  │
  └── 网络异常
      → 回退到 sessionStorage 缓存的 authStatus
      → 无缓存 → 重定向到 /login

3.2 API 调用流程

来源: web/src/lib/api.ts:31-56, web/src/api/client.ts

Page/Component
  │
  │ ① 调用命名空间 API (e.g., sandboxApi.list())
  │
  ├── api/client.ts
  │   - 封装请求参数
  │   - 调用 api() 函数
  │
  ├── lib/api.ts: api()
  │   ├── 构建 URL: /cubeapi/v1 + path + query
  │   ├── 注入标头:
  │   │   ├── X-API-Key: localStorage.cube.apiKey
  │   │   └── X-Session-Token: localStorage.cube.session
  │   ├── fetch() 发送请求
  │   ├── 401/403/500 → 抛出 ApiError(status, message, body)
  │   └── 200/201 → 返回 JSON 响应
  │
  └── TanStack Query
      - 缓存响应
      - refetchInterval 自动刷新
      - 错误重试 (retry: 1)

3.3 沙箱生命周期操作

来源: web/src/api/client.ts:191-214, web/src/pages/Sandboxes.tsx:22-173

操作API 路径方法前端位置
列表/v2/sandboxesGETSandboxesPage.tsx
创建/sandboxesPOSTSandboxNewPage.tsx
详情/sandboxes/:idGETSandboxDetailPage.tsx
销毁/sandboxes/:idDELETESandboxesPage.tsx
暂停/sandboxes/:id/pausePOSTSandboxesPage.tsx
恢复/sandboxes/:id/resumePOSTSandboxesPage.tsx
超时/sandboxes/:id/timeoutPOSTSandboxDetailPage.tsx
日志/v2/sandboxes/:id/logsGETSandboxDetailPage.tsx

3.4 AgentHub 快照与克隆操作

来源: web/src/pages/AgentHub.tsx:927-1120

AgentHub 的快照和克隆采用异步操作模型:

  • 创建快照请求立即返回 operationId
  • 前端乐观占位: 在时间线顶部插入"存档中…“节点
  • 后台轮询操作流水 (listOperations) 获取完成状态
  • 操作完成 → 替换占位为真实数据
  • 操作失败 → 移除占位并显示错误

克隆同样使用乐观占位:

  • 立即在列表中插入 N 张"分身中…“卡片
  • 后台批量调用 clone API
  • 所有请求完成 → 替换占位或显示第一个错误

4. 数据存储

4.1 localStorage 键位表

来源: web/src/lib/session.ts, web/src/store/theme.ts, web/src/pages/Keys.tsx, web/src/lib/mockFlag.ts

Key位置用途持久化
cube.sessionsession.ts:7Session Token永久 (localStorage)
cube.sessionUsersession.ts:8用户名永久 (localStorage)
cube.authStatussession.ts:9认证状态缓存会话 (sessionStorage)
cube.apiKeyKeys.tsx:21API Key永久 (localStorage)
cube-themetheme.ts:8主题模式永久 (localStorage)
cube.langi18n/index.ts:27语言偏好永久 (localStorage)
cube.useMockmockFlag.ts:11Mock 开关永久 (localStorage)

4.2 TanStack Query 缓存配置

来源: web/src/main.tsx:37-41

const qc = new QueryClient({
  defaultOptions: {
    queries: { retry: 1, refetchOnWindowFocus: false, staleTime: 2_000 },
  },
});

各模块的刷新间隔:

QueryrefetchInterval用途
['cluster']10s集群概览
['sandboxes']5s沙箱列表
['templates']30s模板列表
['templates', 'compat']30s模板兼容矩阵
['nodes']15s节点列表
['sandbox', id]5s沙箱详情
['sandbox-logs', id]10s沙箱日志
['runtime-config']60s staleTime运行时配置

5. 安全机制

5.1 认证机制

来源: web/src/components/AuthGuard.tsx:17-54, web/src/lib/api.ts:35-36

两层凭证传递:

API Key:     localStorage("cube.apiKey")   → X-API-Key header
Session:     localStorage("cube.session")  → X-Session-Token header
  • 两个标头同时注入,由服务端决定优先使用哪个
  • AuthGuard 所有非 /login 路由前调用 /auth/session 校验
  • /auth/session 返回 { authRequired, authenticated } 决定放行/重定向

5.2 安全特性

#特性位置说明
S1AuthGuard 路由守卫src/components/AuthGuard.tsx:17-54未认证重定向到 /login
S2双重标头注入 (API Key + Session)src/lib/api.ts:35-44同时注入 X-API-Key 和 X-Session-Token
S3Vite proxy 开发隔离vite.config.ts:42-47仅开发环境生效
S4TypeScript 严格模式tsconfig.json:13编译时类型安全
S5暗色主题无安全隐患tailwind.config.js-
S6sessionStorage 认证状态回退src/components/AuthGuard.tsx:34网络异常时回退到已缓存状态
S7登出清除 localStoragesrc/lib/session.ts:27-31清除所有会话数据
S8密码修改本地校验src/pages/Settings.tsx:239-245长度/确认密码客户端校验

5.3 已知风险

#风险等级说明
R1Token 明文存储 localStorage🟠 中XSS 可窃取 session token 和 API key
R2客户端路由守卫🟡 中仅前端控制,服务端无对应校验
R3无 CSP 标头🟡 中需在反向代理配置
R4MSW Mock Service Worker 生产隐患🟢 低如果打包时意外包含 mock 可能干扰正常请求
R5默认凭据 admin/admin🟡 中登录页预设 username=“admin”,需部署后改密

6. 配置项

6.1 构建时配置

来源: web/vite.config.ts:32-35

define: {
  __APP_VERSION__: JSON.stringify(resolveAppVersion()),
}

版本解析优先级:

  1. 环境变量 CUBE_VERSION (CI/CD 构建时注入)
  2. git describe --tags --abbrev=0 (最近 tag)
  3. package.json version 字段 (兜底)

6.2 环境变量

变量默认值用途位置
VITE_USE_MOCK未设置启用 MSW MockmockFlag.ts:23
VITE_FORCE_LANG未设置强制语言i18n/index.ts:9
VITE_HIDE_AGENT_RECOVER未设置隐藏 Agent 恢复功能AgentHub.tsx:44
CUBE_VERSION自动推导应用版本vite.config.ts:19

6.3 Vite 代理配置

来源: web/vite.config.ts:42-47

server: {
  port: 5173,
  proxy: {
    '/cubeapi': 'http://127.0.0.1:3000',
  },
}
配置项说明
API 代理http://127.0.0.1:3000开发服务器
端口5173Vite 开发端口
前端基础路径/cubeapi/v1API 前缀

6.4 npm scripts

命令用途
npm run dev启动 Vite 开发服务器
npm run buildTypeScript 检查 + 生产构建
npm run preview预览生产构建
npm run lintTypeScript 类型检查
npm run api:export从 CubeAPI 导出 OpenAPI 规范
npm run api:generate从 OpenAPI 生成 TypeScript 类型
npm run api:sync导出 + 生成

7. 关键文件清单

模块路径关键内容
入口web/src/main.tsx:1-89React DOM 渲染 + QueryClient + 路由
路由web/src/main.tsx:49-72路由配置 (Routes)
AuthGuardweb/src/components/AuthGuard.tsx:17-54路由守卫逻辑
API 封装web/src/lib/api.ts:31-56fetch 封装 + ApiError
Session 管理web/src/lib/session.ts:7-40localStorage session CRUD
类型化客户端 (Sandbox)web/src/api/client.ts:191-214sandboxApi
类型化客户端 (Template)web/src/api/client.ts:216-251templateApi
类型化客户端 (Cluster)web/src/api/client.ts:257-268clusterApi
类型化客户端 (Auth)web/src/api/client.ts:413-420authApi
类型化客户端 (AgentHub)web/src/api/client.ts:453-575agentHubApi
生成类型web/src/api/generated/schema.tsOpenAPI 生成类型
登录页web/src/pages/Login.tsx:14-107登录表单 + 错误处理
概览页web/src/pages/Overview.tsx:14-224集群 KPIs + 最近沙箱
沙箱列表web/src/pages/Sandboxes.tsx:22-231搜索/过滤/CRUD
创建沙箱web/src/pages/SandboxNew.tsx:173-261模板选择 + metadata
沙箱详情web/src/pages/SandboxDetail.tsx:34-80详情 + 日志 + 操作
模板管理web/src/pages/Templates.tsx:567-838创建/删除/兼容矩阵
节点列表web/src/pages/Nodes.tsx:14-140健康/资源使用率
API 密钥web/src/pages/Keys.tsx:11-62localStorage 存储
AgentHubweb/src/pages/AgentHub.tsx:135-2461Agent CRUD + 快照 + 克隆
系统设置web/src/pages/Settings.tsx:459-487主题/语言/集群/账户
主题 Storeweb/src/store/theme.ts:30-38Zustand theme store
UI Storeweb/src/store/ui.ts:12-16Zustand command palette
Agent Storeweb/src/state/agentStore.tsAgent 全局状态
i18n 初始化web/src/i18n/index.ts:4-40i18next + 语言检测
全局样式web/src/styles/globals.css:1-239HSL 变量 + 暗色/亮色主题
Vite 配置web/vite.config.ts:1-48代理 + 版本注入
Tailwind 配置web/tailwind.config.js:1-112主题 + 颜色 + 字体
TypeScript 配置web/tsconfig.json:1-23严格模式
MSW Workerweb/src/mocks/browser.ts:4-19dev mock 初始化
Mock 开关web/src/lib/mockFlag.ts:21-35Mock 启用检测

8. 组件树与布局

<React.StrictMode>
  <QueryClientProvider>
    <ThemeProvider>
      <BrowserRouter>
        <Routes>
          /login  →  <LoginPage />
          <AuthGuard>
            <AppShell>
              <Rail />              {/* 左侧固定导航栏 */}
              <main>
                <TopBar />          {/* 顶部栏 */}
                <Outlet />          {/* 页面内容 */}
              </main>
              <CommandPalette />    {/* Cmd+K 命令面板 */}
              <ToastProvider />     {/* Toast 通知 */}
              <HotkeyMount />       {/* 全局快捷键 */}
            </AppShell>
          </AuthGuard>
        </Routes>
      </BrowserRouter>
    </ThemeProvider>
  </QueryClientProvider>
</React.StrictMode>

Rail 导航栏项:

来源: web/src/components/Rail.tsx:23-35

顺序路径图标i18n key说明
1/LayoutDashboardoverview概览
2/sandboxesBoxessandboxes沙箱
3/templatesPackagetemplates模板
4/nodesServernodes节点
5/versionsLayersversions版本
6/networkNetworknetwork网络
7/observabilityActivityobservability可观测性
8/keysKeyRoundapiKeysAPI 密钥
9/storeStorestore模板商店
10/agenthubBotagentHubAI Agent
11/settingsSettingssettings设置

9. API 命名空间总览

来源: web/src/api/client.ts

9.1 sandboxApi

方法API 调用用途
list(params?)GET /v2/sandboxes列沙箱
get(id)GET /sandboxes/:id沙箱详情
kill(id)DELETE /sandboxes/:id销毁
pause(id)POST /sandboxes/:id/pause暂停
resume(id, body)POST /sandboxes/:id/resume恢复
setTimeout(id, seconds)POST /sandboxes/:id/timeout设置超时
logs(id, params?)GET /v2/sandboxes/:id/logs日志
create(body)POST /sandboxes创建

9.2 templateApi

方法API 调用用途
list()GET /templates列模板
get(id)GET /templates/:id模板详情
create(body)POST /templates创建
rebuild(id)POST /templates/:id重建
remove(id)DELETE /templates/:id删除
compat()GET /templates/compat兼容矩阵
getBuildStatus(id, buildID)GET /templates/:id/builds/:buildID/status构建状态
getBuildLogs(id, buildID)GET /templates/:id/builds/:buildID/logs构建日志
adoptCompatBaseline(id)POST /templates/compat/:id/adopt-baseline采纳基线

9.3 clusterApi

方法API 调用用途
overview()GET /cluster/overview集群概览
nodes()GET /nodes节点列表
node(id)GET /nodes/:id节点详情
config()GET /config运行时配置

9.4 authApi

方法API 调用用途
session()GET /auth/session检查 session
login(body)POST /auth/login登录
logout()POST /auth/logout登出
changePassword(body)POST /auth/change-password改密码

9.5 storeApi

方法API 调用用途
meta()GET /store/meta镜像元信息
refresh()POST /store/refresh刷新 store

9.6 agentHubApi

方法API 调用用途
list()GET /agenthub/instances列 Agent 实例
create(body)POST /agenthub/instances创建 Agent
delete(id)DELETE /agenthub/instances/:id删除
restart(id)POST /agenthub/instances/:id/restart重启
pause(id)POST /agenthub/instances/:id/pause暂停
resume(id)POST /agenthub/instances/:id/resume恢复
upgrade(id)POST /agenthub/instances/:id/upgrade升级
updateModel(id, body)PUT /agenthub/instances/:id/model更新模型
listSnapshots(id)GET /agenthub/instances/:id/snapshots列快照
createSnapshot(id, body)POST /agenthub/instances/:id/snapshots创建快照
deleteSnapshot(id, snapshotId)DELETE .../snapshots/:snapshotId删除快照
rollback(id, body)POST .../:id/rollback回滚
clone(id, body)POST .../:id/clone克隆
recover(id)POST .../:id/recover恢复
publishTemplate(id, body)POST .../:id/publish-template发布模板
getSettings()GET /agenthub/settingsAgent 设置
updateSettings(body)PUT /agenthub/settings更新设置

10. UI 主题系统

10.1 颜色系统

来源: web/src/styles/globals.css, web/tailwind.config.js

使用 HSL CSS 变量实现明暗双主题:

/* 暗色 (默认) — Cube Midnight */
:root, .dark {
  --background: 215 35% 5%;        /* 深空黑 */
  --foreground: 210 40% 96%;       /* 亮白 */
  --primary: 220 85% 64%;          /* 蓝紫 */
  --cube-ok: 158 64% 50%;          /* 翠绿 */
  --cube-warn: 32 95% 60%;         /* 琥珀 */
  --cube-err: 0 72% 62%;           /* 玫瑰红 */
}

/* 亮色 — 暖白纸感 */
.light {
  --background: 40 20% 97%;        /* 象牙白 */
  --foreground: 20 15% 15%;        /* 墨色 */
  --primary: 212 55% 42%;          /* 深蓝 */
}

10.2 主题切换

来源: web/src/store/theme.ts:6-38

  • 三种模式: light | dark | system
  • 读取 prefers-color-scheme media query 实现 system 模式
  • 切换时自动监听系统主题变化
  • 持久化到 localStorage key cube-theme

11. 国际化系统

来源: web/src/i18n/index.ts:4-40

  • 引擎: i18next + react-i18next
  • 检测: i18next-browser-languagedetector (localStorage > navigator)
  • 语言: en (英语), zh (简体中文)
  • 命名空间: common, nav, topbar, command, overview, sandboxes, sandboxDetail, sandboxNew, templates, templateDetail, nodes, nodeDetail, network, keys, placeholder, settings, observability, store, agentHub, auth (共 20 个)
  • 缓存: localStorage key cube.lang
  • HTML lang: 自动同步到 <html lang>

12. 开发辅助工具

12.1 MSW Mock

来源: web/src/mocks/browser.ts, web/src/lib/mockFlag.ts

  • 开发环境 Mock Service Worker
  • 启用方式:
    • VITE_USE_MOCK=1 环境变量
    • ?mock=1 URL query (自动持久化)
    • localStorage.setItem('cube.useMock', '1')
  • 所有未匹配的请求 bypass 放行

12.2 命令面板

来源: web/src/components/CommandPalette.tsx

  • 快捷键: Cmd+K / Ctrl+K
  • 基于 cmdk 库实现
  • 状态管理: Zustand useCommandPaletteStore

13. 总结: 架构设计与安全权衡

  1. 现代 React 技术栈: Vite 6 开发服务器 + TanStack Query 声明式数据获取 + Zustand 轻量状态管理,配合 shadcn 组件风格,兼顾开发效率和 UI 一致性。

  2. 类型安全 API 客户端: 通过 openapi-typescript 从 OpenAPI 规范自动生成 TypeScript 类型,实现端到端类型安全,减少运行时错误。

  3. 客户端路由守卫: AuthGuard 通过 /auth/session 端点检查认证状态,但仅为客户端安全措施。服务端 (CubeAPI) 对 WebUI 内部 API 的鉴权通过 x-session-token 独立实现。

  4. 双重凭证注入: API 调用同时携带 X-API-KeyX-Session-Token,由服务端决策使用何种认证方式,灵活支持 SDK 和 WebUI 两种使用场景。

  5. Token 明文存储 localStorage: session token 和 API key 均以明文存储在 localStorage 中。这是 SPA 的常见做法 (非 HttpOnly cookie),存在 XSS 窃取风险。

  6. 国际化深度集成: 20 个翻译命名空间覆盖所有页面,支持 en/zh 双语,语言偏好持久化到 localStorage。

  7. 乐观更新模式: AgentHub 的快照和克隆操作采用乐观占位 + 后台轮询模式,提升用户体验。

  8. 预留可扩展性: 可观测性和网络页面已预留路由,等待后端能力成熟后填充。

  9. Mock 系统: 开发环境通过 MSW 实现前端模拟,支持通过环境变量/URL/localStorage 三种方式启用,可独立于后端进行开发和调试。