XiStudio 技术架构 v2.0 · Shell + Monorepo
文档定位
- 版本变更:v1.0(2026 早期 · .NET 8 + Electron 方向)→ v2.0(本文 · Monorepo Shell + Vue 3 纯 web)
- 上游:D0 产品矩阵 V1.1 · D3-FE-ARCH-001 顶层架构 · D3-FE-ARCH-003 共享 UI kit 架构
- 下游:D3-FE-PLAN-004 XiStudio Shell 实现 plan
- 架构约束:严格遵循 D3-FE-ARCH-001 第 3.3 节的 C-01 ~ C-10 约束
1. 产品定位与目标
1.1 产品定位
XiStudio 是 Xisound 生态的总入口,定位"可视化音频算法开发 IDE"(L4 层)。技术层面承担:
- Shell 容器:内嵌 XiForge(锻造台)和 XiVST(插件商店)作为子面板
- 生态枢纽:通过 deep-link 呼起 XiTune / XiTest / XiProbe
- MC 能力继承者:现有 MC(Module Chain)链路编辑器升级为 XiStudio 的 Link Editor 核心模块
- AI Copilot 承载者:XiMind 作为右侧抽屉常驻
1.2 版本矩阵与 GA 节奏
| 版本 | 时点 | 状态 | 覆盖能力 |
|---|---|---|---|
| Alpha | Y1Q1 | 规划 | Shell 骨架 + Hello World |
| Beta | Y1Q2 | 规划 | Link Editor(MC 迁移)+ Project Manager |
| v1.0 GA | Y1Q4 | 里程碑 | 完整 Shell + Link Editor + Compile & Burn + Algo Library Browser + Tool Launcher |
| v2.0 | Y2Q1 | 规划 | 内嵌 XiForge Alpha + XiVST Beta |
| v3.0 Copilot | Y3Q1 | 规划 | XiMind 深度集成 · 自然语言驱动 |
1.3 目标用户与核心场景
| 用户类型 | 核心场景 | XiStudio 提供的能力 |
|---|---|---|
| Tier1 算法工程师 | 搭建 DSP 算法链路 | Link Editor · 模块库 · 编译烧录 |
| OEM 集成工程师 | 管理整车声学工程 | Project Manager · 版本控制 · 多车型管理 |
| 客户算法工程师 | 开发自定义模块 | 内嵌 XiForge 面板 |
| 灯塔项目交付工程师 | 快速上线 | 预设模板 + AI Copilot |
| 车载系统集成工程师 ⭐ | 接入 CAN/速度/音量等车辆信号 | Signal Flow Editor(§4.8) |
1.4 竞品对标(XiStudio 视角)
XiStudio 明确对标车载 DSP 开发 IDE 的三家标杆产品(完整对照见 D3-FE-ARCH-001 §1.4):
| 竞品 | XiStudio 借鉴的关键设计 |
|---|---|
| AudioWeaver(DSP Concept) | 算法链路画布交互范式 · Module Manifest + PortInfo propagation · 模块库分类组织 |
| SigmaStudio(ADI) | 硬件烧录紧耦合 · Compile & Burn 一体化体验 · 芯片端直接映射 |
| LiveAmp ⭐(首选风格) | 独立 Signal Flow 画布(§4.8)· 实时信号值可视化 · 车载信号接入工程化 · 调音 UI 运行时 |
XiStudio 的三画布体系(对标 LiveAmp 的核心差异化设计):
- LinkEditor 画布(§4.2)· 算法画布 · 对标 AudioWeaver 主画布
- Signal Flow Editor 画布(§4.8)· 信号画布 · ⭐ 对标 LiveAmp Signal Flow
- 内嵌 XiForge 的 UI Designer 画布(详见 D2-P9 §4.3)· UI 控件画布 · 对标 LiveAmp 调音 UI
三画布职责严格分离、底层共享 @xi/ui-kit 的 Canvas 能力,避免单画布节点爆炸导致 AudioWeaver 式的"ParameterSetGet 散落主画布"问题。
2. 架构总览
2.1 XiStudio 在 Monorepo 中的位置
graph TB
subgraph Apps["apps/"]
subgraph Studio["xi-studio(本文)"]
Shell["Shell"]
Router["vue-router"]
Stores["Stores"]
AICopilot["AICopilot"]
end
Forge["xi-forge<br/>(内嵌组件)"]
VST["xi-vst<br/>(内嵌组件)"]
Tune["xi-tune<br/>(deep-link 呼起)"]
Test["xi-test<br/>(deep-link 呼起)"]
Probe["xi-probe<br/>(deep-link 呼起)"]
end
subgraph Packages["packages/"]
UIKit["@xi/ui-kit"]
Protocol["@xi/protocol"]
StoreCore["@xi/store-core"]
DSPUtils["@xi/dsp-utils"]
AISDK["@xi/ai-sdk"]
end
Studio --> UIKit
Studio --> Protocol
Studio --> StoreCore
Studio --> DSPUtils
Studio --> AISDK
Studio -.内嵌.-> Forge
Studio -.内嵌.-> VST
Studio -.deep-link.-> Tune
Studio -.deep-link.-> Test
Studio -.deep-link.-> Probe
class Studio,Shell,Router,Stores,AICopilot xyL4
class Forge,VST xyL3
class Tune,Test,Probe xyL2
class UIKit,Protocol,StoreCore,DSPUtils,AISDK xyL1
class Apps xySgL4; class Studio xySgL4; class Packages xySgL4;
2.2 内部模块架构
graph TB
subgraph Shell["Workspace Shell"]
TopBar["Top Bar<br/>(工程名 / 用户 / 保存状态)"]
SideNav["Side Nav<br/>(产品切换 + 模块快捷)"]
MainArea["Main Area<br/>(当前路由视图)"]
CopilotDrawer["Right Drawer<br/>(AI Copilot)"]
StatusBar["Status Bar<br/>(硬件 / 日志 / 提示)"]
end
subgraph Routes["路由视图"]
Workspace["/workspace<br/>项目总览"]
LinkEditor["/project/:id/link<br/>链路编辑器(算法画布)"]
SignalFlow["/project/:id/signal<br/>⭐ Signal Flow Editor(信号画布)"]
Compile["/project/:id/compile<br/>编译烧录"]
AlgoLib["/algo-library<br/>算法库浏览"]
Tools["/tools<br/>工具启动器"]
ForgePanel["/forge<br/>XiForge 内嵌"]
VSTPanel["/vst<br/>XiVST 内嵌"]
end
MainArea --> Workspace
MainArea --> LinkEditor
MainArea --> SignalFlow
MainArea --> Compile
MainArea --> AlgoLib
MainArea --> Tools
MainArea --> ForgePanel
MainArea --> VSTPanel
LinkEditor -.bindings.-> SignalFlow
class TopBar,SideNav,MainArea,CopilotDrawer,StatusBar xyL4
class Workspace,LinkEditor,Compile,AlgoLib,Tools,ForgePanel,VSTPanel xyL2
class SignalFlow xyL3
class Shell xySgL4; class Routes xySgL2;
2.3 技术栈
| 层 | 选型 | 来源 |
|---|---|---|
| 框架 | Vue 3.4+ | 延续 / D3-FE-ARCH-001 §7.1 |
| 路由 | vue-router 4 | 新增替换 appMode |
| 状态 | Pinia 2+ | 延续 |
| UI | @xi/ui-kit + Tailwind CSS 3+ | D3-FE-ARCH-003 |
| 协议 | @xi/protocol(WebSocket + HTTP + deep-link) | D3-FE-ARCH-003 |
| AI | @xi/ai-sdk(Copilot) | D3-FE-ARCH-003 |
| 构建 | Vite 5+ | 延续 |
| 测试 | Vitest + @playwright/test | 延续 |
3. 目录结构
apps/xi-studio/
├── src/
│ ├── main.ts # Vue app 入口
│ ├── App.vue # 根组件(Shell 布局)
│ ├── router/
│ │ ├── index.ts # 路由定义
│ │ └── guards.ts # 认证 / 未保存提示 guard
│ ├── layouts/
│ │ ├── ShellLayout.vue # 主布局(TopBar + SideNav + MainArea + CopilotDrawer + StatusBar)
│ │ └── FullScreenLayout.vue # 编译/预览等全屏布局
│ ├── views/
│ │ ├── WorkspaceView.vue # /workspace
│ │ ├── LinkEditorView.vue # /project/:id/link
│ │ ├── CompileView.vue # /project/:id/compile
│ │ ├── AlgoLibraryView.vue # /algo-library
│ │ ├── ToolsView.vue # /tools(启动器)
│ │ ├── SignalFlowView.vue # ⭐ /project/:id/signal(Signal Flow Editor)
│ │ ├── ForgePanelView.vue # /forge(内嵌 XiForge)
│ │ └── VSTPanelView.vue # /vst(内嵌 XiVST)
│ ├── components/
│ │ ├── shell/ # Shell 专用组件
│ │ │ ├── TopBar.vue
│ │ │ ├── SideNav.vue
│ │ │ ├── StatusBar.vue
│ │ │ └── CopilotDrawer.vue
│ │ ├── link-editor/ # Link Editor 专用(Studio 特有逻辑)
│ │ │ ├── ModuleLibraryPanel.vue
│ │ │ ├── ParamInspectorPanel.vue
│ │ │ └── RunControlBar.vue
│ │ ├── signal-flow/ # ⭐ Signal Flow Editor 专用(对标 LiveAmp)
│ │ │ ├── SignalNodePalette.vue # 左侧信号模块库(signal_common + 运算节点)
│ │ │ ├── BindingInspector.vue # 算法 bind 管理面板
│ │ │ ├── SignalLiveMonitor.vue # 右侧实时值监视
│ │ │ └── DeepLinkBridge.vue # 与 LinkEditor 的 bind 跳转
│ │ ├── project/
│ │ │ ├── ProjectCard.vue
│ │ │ └── ProjectCreateModal.vue
│ │ └── tools/
│ │ └── ToolLauncherCard.vue
│ ├── stores/
│ │ ├── useWorkspaceStore.ts # 当前打开的工程 / 窗口状态
│ │ ├── useProjectStore.ts # 工程 CRUD · 版本管理
│ │ ├── useLinkStore.ts # 当前链路(继承 @xi/store-core 的 LinkModel)
│ │ ├── useSignalFlowStore.ts # ⭐ 信号图谱 + bindings CRUD + liveValues
│ │ ├── useCompileStore.ts # 编译任务
│ │ └── useAlgoLibStore.ts # 算法库浏览状态
│ ├── services/
│ │ ├── backendApi.ts # 后端 HTTP 封装(经 @xi/protocol)
│ │ ├── audioEngine.ts # 音频引擎 WebSocket 连接
│ │ └── deepLink.ts # 呼起其他 app 的辅助
│ └── assets/
│ └── styles/
│ └── main.css # tailwind + 全局样式
├── public/
│ └── favicon.svg
├── tests/
│ ├── unit/
│ └── e2e/
├── vite.config.ts
├── tailwind.config.ts # extends @xi/ui-kit preset
├── tsconfig.json
├── package.json # 依赖 @xi/* packages + @xi-apps/xi-forge + @xi-apps/xi-vst
└── README.md
4. 核心模块详细设计
4.1 Workspace Shell(Shell 布局)
职责:提供稳定的壳,所有页面视图嵌入其中。
组件层次:
<App>
<ShellLayout>
<TopBar /> # 固定高 48px
<div class="flex">
<SideNav /> # 固定宽 64px(折叠)/ 240px(展开)
<main>
<router-view /> # 路由视图
</main>
<CopilotDrawer /> # 可收起 · 默认 400px 宽
</div>
<StatusBar /> # 固定高 24px
</ShellLayout>
</App>
关键状态:
useWorkspaceStore.activeProject:当前打开的工程useWorkspaceStore.sidebarCollapsed:侧栏折叠状态useWorkspaceStore.copilotVisible:Copilot 显示/隐藏useLayoutStore.splitSizes(来自 store-core):分栏尺寸持久化
4.2 Link Editor(MC 迁移核心)
职责:链路的可视化搭建、参数调整、运行预览。这是 XiStudio 最核心的交互入口,继承现有 MC 全部能力。
视图层级:
<LinkEditorView>
<SplitPane horizontal>
<LinkEditorHeader /> # 运行按钮 / 模式切换 / 保存
<SplitPane vertical>
<ModuleLibraryPanel /> # 左侧模块库(使用 @xi/ui-kit <ModulePalette>)
<LinkCanvas # 中央画布(使用 @xi/ui-kit <LinkCanvas>)
:modules="link.modules"
:connections="link.connections"
@module-move="onModuleMove"
@connection-add="onConnectionAdd"
/>
<ParamInspectorPanel /> # 右侧属性面板(使用 @xi/ui-kit <PropertyEditor>)
</SplitPane>
</SplitPane>
</LinkEditorView>
数据流:
sequenceDiagram
participant UI as LinkEditorView
participant Store as useLinkStore
participant SC as @xi/store-core LinkModel
participant WS as audioEngine (WebSocket)
participant BE as Backend
UI->>Store: 添加模块(moduleType, position)
Store->>SC: createModule(type, pos)
SC-->>Store: ModuleModel
Store->>Store: link.modules.push(module)
UI->>UI: 重新渲染 LinkCanvas
UI->>Store: updateParam(moduleId, key, value)
Store->>WS: send ControlCommand{type: 'update-param'}
WS->>BE: WebSocket message
BE-->>WS: AudioEngineEvent{type: 'level-meter'}
WS-->>Store: 更新运行态
UI->>UI: 刷新电平表
从现有 MC 迁移的能力清单:
| 现有能力 | 目标位置 | 改动 |
|---|---|---|
| 拖拽添加模块 | <LinkCanvas> 的 onDrop + useLinkStore |
新写(基于 @xi/ui-kit) |
| 连线 | <LinkCanvas> 内置能力 |
新写 |
| 参数编辑 | <PropertyEditor> + useLinkStore.updateParam |
新写 |
| 保存/加载链路 | useLinkStore + backendApi | 迁移现有 linkStore 业务逻辑 |
| 运行/停止 | audioEngine 服务 + useLinkStore.runState | 迁移 |
| 模块库浏览 | <ModulePalette> + useAlgoLibStore |
抽取 |
| XML tuning 兼容模式 | 保留独立路由 /project/:id/xml-tune(仅 Studio 有) |
兼容 |
4.3 Project Manager
职责:工程文件的新建、打开、保存、版本管理、云同步。
核心 API(useProjectStore):
interface ProjectStore {
projects: Ref<ProjectSummary[]>
activeProject: Ref<Project | null>
async list(): Promise<ProjectSummary[]>
async create(name: string, template?: string): Promise<Project>
async open(id: string): Promise<Project>
async save(project: Project): Promise<void>
async saveAs(project: Project, newName: string): Promise<Project>
async delete(id: string): Promise<void>
async listVersions(projectId: string): Promise<ProjectVersion[]>
async restoreVersion(projectId: string, version: string): Promise<void>
async sync(project: Project): Promise<SyncResult>
}
后端契约:通过 @xi/protocol 的 http/projects.ts 定义(Docs-First)。
4.4 Compile & Burn
职责:将链路编译为 DSP 可执行产物,并烧录到硬件。
流程:
stateDiagram-v2
[*] --> Idle
Idle --> Validating: 点击"编译"
Validating --> Compiling: 校验通过
Validating --> Idle: 校验失败
Compiling --> CompileDone: 云端编译完成
Compiling --> CompileError: 编译报错
CompileDone --> ReadyToBurn: 产物下载
ReadyToBurn --> Burning: 点击"烧录"
Burning --> BurnDone: 硬件应答 OK
Burning --> BurnError: 硬件无应答/校验失败
BurnDone --> [*]
视图:CompileView.vue 显示编译日志 + 产物列表 + 硬件选择 + 烧录进度。
4.5 Algo Library Browser(含 XiVST 内嵌)
职责:浏览 XiAlgo 六大套件 + XiVST Marketplace 插件(通过内嵌 <VSTPanel>)。
路由结构:
/algo-library # 总览
/algo-library/xialgo # XiAlgo 套件
/algo-library/xialgo/:id # 算法详情
/algo-library/xivst # XiVST Marketplace(内嵌 @xi-apps/xi-vst 的 <VSTPanel>)
/algo-library/private # 私有仓库(来自 XiForge)
内嵌 XiVST 实现:
<!-- VSTPanelView.vue -->
<template>
<VSTPanel
:mode="'embedded'"
:project-context="activeProject"
@plugin-installed="onPluginInstalled"
/>
</template>
<script setup lang="ts">
import { VSTPanel } from '@xi-apps/xi-vst/embedded'
</script>
4.6 Tool Launcher(deep-link 呼起 Tune/Test/Probe)
职责:从 XiStudio 打开其他独立 app,携带当前工程上下文。
核心服务:
// services/deepLink.ts
import { buildDeepLink } from '@xi/protocol/deep-link'
import { useAuthStore } from '@xi/store-core'
export async function openTool(tool: 'xi-tune' | 'xi-test' | 'xi-probe', params: {
intent?: string
projectId?: string
}) {
const auth = useAuthStore()
// 1. 向后端换取短时效一次性 token(不直接传长期 token)
const tmpToken = await backendApi.exchangeToolToken(tool, params.projectId)
// 2. 构造 deep-link
const url = buildDeepLink({
app: tool,
route: params.intent ? `/intent/${params.intent}` : '/',
params: {
project: params.projectId ?? '',
token: tmpToken,
},
})
// 3. web 场景:新 tab;Y2 桌面场景:Tauri shell.open
window.open(url, '_blank')
}
4.7 AI Copilot 集成
职责:XiMind 的 UI 承载。
实现:
<!-- components/shell/CopilotDrawer.vue -->
<template>
<Drawer v-model="visible" position="right" :width="400">
<CopilotDrawer :session="session" />
</Drawer>
</template>
<script setup lang="ts">
import { Drawer } from '@xi/ui-kit'
import { CopilotDrawer, useCopilot } from '@xi/ai-sdk'
import { useLinkStore } from '@/stores/useLinkStore'
const linkStore = useLinkStore()
const { session } = useCopilot({
tenantId: 'xisound',
context: () => ({
app: 'xi-studio',
currentProject: linkStore.activeProjectId,
currentLink: linkStore.currentLink,
}),
})
// 注册 function-calling 工具(Studio 特有)
session.value?.registerTool({
name: 'update-link',
description: '修改当前链路(增删模块/改连接)',
parameters: UpdateLinkParamsSchema,
execute: async (params) => {
await linkStore.applyAIUpdate(params)
return { success: true }
},
})
</script>
4.8 Signal Flow Editor(⭐ 新增 · 对标 LiveAmp · 信号画布)
职责:独立于 LinkEditor 的信号画布,管理车载系统信号(CAN / GPIO / 速度 / 音量 / 事件等)的采集 → 运算 → 输出,供 LinkEditor 中的算法模块通过 externalBind 订阅。对标 LiveAmp 的 Signal Flow 画布。
路由:/project/:id/signal · View:SignalFlowView.vue
视图层级:
<SignalFlowView>
<SplitPane horizontal>
<SignalFlowHeader /> # 保存 / 撤销 / 布局按钮 / 实时值开关
<SplitPane vertical>
<SignalNodePalette /> # 左侧:signal_common + 11 个运算节点
<SignalCanvas # 中央画布(来自 @xi/ui-kit)
:nodes="signalFlow.nodes"
:connections="signalFlow.connections"
:live-values="signalFlow.liveValues"
@node-move="onNodeMove"
@connection-add="onConnectionAdd"
/>
<BindingInspector /> # 右侧:当前选中节点 + bindings 列表
</SplitPane>
<SignalLiveMonitor /> # 底部可折叠:当前 session 所有信号实时值监控
</SplitPane>
</SignalFlowView>
核心能力:
| 能力 | 说明 |
|---|---|
| 节点拖放 | 从 SignalNodePalette 拖 signal_common_v1 设置信号名/sourceType/范围;拖运算节点组合成信号链 |
| 连线 | control-rate(100~1000Hz)连线,与 LinkEditor 的 audio-rate 连线视觉区分(动画粒子流) |
| 实时值显示 | 每个节点内显示当前信号值(LiveAmp 标志性特征)· 100Hz 刷新 |
| 算法 bind 管理 | 在 BindingInspector 查看/编辑 / 删除"算法模块 ← 信号"的订阅关系 |
| DeepLink 跳转 | 点 "查看绑定模块" 跳回 LinkEditor 定位对应模块 |
| Save/Load | 持久化到 link.json 的 signalGraph 和 bindings 段(见 D3-FE-ARCH-001 §5.8.5) |
数据流:
sequenceDiagram
participant UI as SignalFlowView
participant Store as useSignalFlowStore
participant WS as audioEngine (WebSocket)
participant BE as Backend (SignalBusService)
participant DSP as DSP control-bus
UI->>Store: 拖放 signal_common_v1 到画布
Store->>Store: nodes.push(signalCommon)
UI->>Store: 激活信号(sourceType=can / signalName="vehicle.speed")
Store->>WS: SignalControlCommand{type:'signal-activate'}
WS->>BE: activate CAN signal
BE->>DSP: 写入 control-bus
DSP-->>BE: 实时值 100Hz 推送
BE-->>WS: SignalValueEvent{signalName, value, ts}
WS-->>Store: 更新 liveValues[nodeId]
Store-->>UI: 节点内实时值刷新
UI->>Store: 在 BindingInspector 新增 binding(moduleId=gain#3, paramKey=gain, signalName=vehicle.speed.smoothed)
Store->>WS: 发送 update-link command (含 bindings)
WS->>BE: BindingResolver.apply(bindings)
BE->>DSP: 设置 binding_table
Note over DSP: Process 函数内读取 bind 值:current_gain = bus_read("...") * base_gain
关键 store:useSignalFlowStore(§6.3)
对标 LiveAmp 的差异化设计:
| LiveAmp 特性 | XiStudio Signal Flow Editor 实现 |
|---|---|
| 独立画布(与 Audio 画布分离) | ✅ /project/:id/signal 独立路由 + <SignalCanvas> 专用组件 |
| 节点实时值显示 | ✅ SignalValueEvent 100Hz 推送 · 节点内 RAF 节流渲染 |
| 信号运算模块(平滑/映射/阈值) | ✅ 11 个运算模块(见 D3-FE-ARCH-001 §5.8.2)· 归属 signalManagement 分类 |
| 订阅式引用(算法 bind 信号名) | ✅ externalBind 字段 + ParamBinding schema |
| Signal Flow 与 Audio Flow 解耦 | ✅ control-bus / audio-bus 双 bus 架构 + link.json 三段结构 |
详细架构:见 D3-FE-ARCH-001 §5.8 Signal I/O 系统 + D3-FE-ARCH-003 §2.3 <SignalCanvas> 组件 + §3.3 Signal I/O WebSocket 消息 + D3-FE-ARCH-004 PLAN-011 实现计划。
5. 路由设计
5.1 路由树
// router/index.ts
const routes: RouteRecordRaw[] = [
{
path: '/',
component: ShellLayout,
children: [
{ path: '', redirect: '/workspace' },
{ path: 'workspace', component: WorkspaceView, meta: { title: '工作台' } },
{
path: 'project/:id',
component: ProjectContextLayout, // 加载工程上下文
children: [
{ path: '', redirect: 'link' },
{ path: 'link', component: LinkEditorView, meta: { title: '链路编辑器(算法画布)' } },
{ path: 'signal', component: SignalFlowView, meta: { title: 'Signal Flow(信号画布)' } }, // ⭐ 新增
{ path: 'compile', component: CompileView, meta: { title: '编译烧录' } },
{ path: 'xml-tune', component: XmlTuneCompatView, meta: { title: 'XML 调音(兼容)' } },
],
},
{ path: 'algo-library', component: AlgoLibraryView, meta: { title: '算法库' } },
{ path: 'algo-library/xivst', component: VSTPanelView, meta: { title: 'XiVST Marketplace' } },
{ path: 'tools', component: ToolsView, meta: { title: '工具' } },
{ path: 'forge', component: ForgePanelView, meta: { title: 'XiForge 锻造台' } },
{ path: 'settings', component: SettingsView, meta: { title: '设置' } },
],
},
{
path: '/login',
component: LoginView, // 使用 @xi/ui-kit + @xi/store-core 的 useAuthStore
},
{
path: '/:pathMatch(.*)*',
component: NotFoundView,
},
]
5.2 路由守卫
- 认证守卫:未登录跳
/login(除公开页外) - 未保存提示:离开 Link Editor 时若
linkStore.isDirty弹确认框 - 工程上下文加载:
/project/:id/*进入时加载工程数据并注入 Pinia
6. Store 设计
6.1 Store 列表
| Store | 职责 | 持久化 | 依赖 |
|---|---|---|---|
useWorkspaceStore |
当前打开工程 + UI 状态(侧栏/Copilot 显示) | localStorage | — |
useProjectStore |
工程 CRUD | 否 | backendApi |
useLinkStore |
当前链路数据 + 运行态 | 否(靠 useProjectStore 持久化) | @xi/store-core LinkModel |
useSignalFlowStore ⭐ |
信号图谱 + bindings + liveValues(§6.3) | 否(靠 useProjectStore 持久化) | @xi/store-core SignalGraphModel |
useCompileStore |
编译任务状态 | 否 | backendApi |
useAlgoLibStore |
算法库浏览状态(筛选 / 搜索词) | sessionStorage | backendApi |
6.2 useLinkStore 核心 API
export const useLinkStore = defineStore('xi-studio-link', () => {
const currentLink = ref<LinkModel | null>(null)
const isDirty = ref(false)
const runState = ref<'idle' | 'running' | 'error'>('idle')
const selectedIds = ref<string[]>([])
function addModule(type: string, position: Position): void
function removeModule(id: string): void
function updateParam(moduleId: string, key: string, value: any): void
function addConnection(from: PortRef, to: PortRef): void
function removeConnection(id: string): void
async function run(): Promise<void>
async function stop(): Promise<void>
async function save(): Promise<void>
async function applyAIUpdate(patch: LinkPatch): Promise<void>
function subscribeEngineEvents(): void // 订阅 audioEngine WS 事件
return { currentLink, isDirty, runState, selectedIds, addModule, removeModule, ... }
})
6.3 useSignalFlowStore 核心 API(⭐ 新增)
import type { SignalGraphModel, SignalNode, ControlWire, ParamBinding } from '@xi/store-core'
export const useSignalFlowStore = defineStore('xi-studio-signal-flow', () => {
// 状态
const graph = ref<SignalGraphModel>({ modules: [], connections: [] })
const bindings = ref<ParamBinding[]>([])
const liveValues = ref<Record<string, number>>({}) // signalName → 当前值
const selectedNodeId = ref<string | null>(null)
const isDirty = ref(false)
// 信号图谱 CRUD
function addNode(type: SignalNode['type'], position: Position): void
function removeNode(id: string): void
function updateNodeParams(id: string, patch: Partial<SignalNode['params']>): void
function addConnection(from: PortRef, to: PortRef): void
function removeConnection(id: string): void
// 信号激活/停用
async function activateSignal(nodeId: string): Promise<void> // 发送 signal-activate command
async function deactivateSignal(nodeId: string): Promise<void>
async function writeSignal(signalName: string, value: number): Promise<void> // 测试用途 signal-write
// Bindings 管理
function addBinding(binding: ParamBinding): void
function removeBinding(moduleId: string, paramKey: string): void
function listBindingsForModule(moduleId: string): ParamBinding[]
// 实时值订阅
function subscribeLiveValues(): void // WS 建立 signal-value-event 订阅
function unsubscribeLiveValues(): void
// 持久化
async function save(): Promise<void>
async function loadFromProject(project: Project): Promise<void>
return { graph, bindings, liveValues, selectedNodeId, isDirty, addNode, ... }
})
与 @xi/protocol 的契约依赖:
signal-flow/signal-node.ts· SignalNode / SignalCommonParamssignal-flow/signal-graph.ts· SignalGraphModelsignal-flow/bindings.ts· ParamBindingwebsocket/signal-value-event.ts· 订阅实时值websocket/signal-control-command.ts· 激活/停用/写入信号
7. 与后端的接口契约
7.1 HTTP API
| 端点 | 方法 | 用途 | Schema(@xi/protocol) |
|---|---|---|---|
/api/projects |
GET/POST | 工程列表/创建 | http/projects.ts |
/api/projects/:id |
GET/PUT/DELETE | 工程 CRUD | http/projects.ts |
/api/projects/:id/versions |
GET | 版本列表 | http/projects.ts |
/api/algo-library |
GET | XiAlgo + 私有 + VST 合并浏览 | http/algo-library.ts |
/api/compile |
POST | 提交编译任务 | http/compile.ts(待建) |
/api/compile/:taskId |
GET | 查询编译进度 | http/compile.ts |
/api/burn/:deviceId |
POST | 烧录固件 | http/burn.ts(待建) |
/api/tool-token |
POST | 换取 deep-link 一次性 token | http/auth.ts(待建) |
7.2 WebSocket
- 端点:
wss://backend/ws/audio-engine - 消息:
@xi/protocol/websocket/audio-engine-event.ts定义的所有 type@xi/protocol/websocket/signal-value-event.ts⭐ 信号实时值推送(对标 LiveAmp)
- 命令:
@xi/protocol/websocket/control-command.ts定义的所有 type@xi/protocol/websocket/signal-control-command.ts⭐ 信号命令(激活/停用/写入/订阅)
8. 测试策略
8.1 单元测试(Vitest)
- Store 测试:useLinkStore / useProjectStore 的 CRUD + dirty 标记 + AI 更新
- 组件测试:各 view 用
@vue/test-utils(浅渲染 + props 验证) - 目标覆盖率:≥ 70%
8.2 e2e 测试(Playwright)
核心场景(必测):
| 场景 | 步骤 | 断言 |
|---|---|---|
| 登录 → 新建工程 | 填登录 + 新建工程表单 | 跳转到 /project/:id/link |
| 拖拽 3 模块成链 | 从 ModulePalette 拖 3 模块 + 连线 | 画布有 3 节点 + 2 连接 |
| 参数编辑 + 保存 | 点模块 → 改参数 → Ctrl+S | Toast "保存成功" + isDirty=false |
| 关闭未保存提示 | 改后直接关闭 | 弹确认框 |
| 呼起 XiTune | 点 Tools → XiTune | 新 tab 打开 xi://xi-tune/... |
| 打开 Copilot 提问 | 打开抽屉 + 输入问题 | 流式响应 |
8.3 性能基线
- 打开含 100 模块的工程:< 2s
- LinkCanvas 60 FPS 拖拽
- Copilot 首字节响应 < 1s(与 XiMind 后端指标一致)
9. 非功能性要求
9.1 可访问性(a11y)
- 所有交互控件支持键盘导航(Tab / Enter / Arrow keys)
- ARIA 标签完整
- 对比度遵循 WCAG AA
9.2 i18n
- zh-CN / en-US 双语(初版)
- 所有文案走
@xi/store-core的 useI18nStore
9.3 主题
- 明/暗/跟随系统三模式(通过 useThemeStore)
- 自定义主题色(企业品牌色)
9.4 浏览器兼容
- Chrome/Edge ≥ 110
- Safari ≥ 16
- Firefox ≥ 110
- 不支持 IE
10. DQ 与风险
10.1 本产品新增 DQ
| DQ 编号 | 问题 | 建议 |
|---|---|---|
| DQ-STUDIO-01 | XML tuning 兼容模式是否保留 | 保留独立路由 /project/:id/xml-tune · Y2 评估是否弃用 |
| DQ-STUDIO-02 | 是否支持多标签页(同时打开多个工程) | Y1 不支持 · Y2 再议 |
| DQ-STUDIO-03 | 内嵌 XiForge 时是否允许独立运行 XiForge dev server | Y1 只允许 Studio 内嵌 · 开发阶段可用 Storybook |
| DQ-STUDIO-04 ⭐ | Signal Flow Editor 是否支持算法画布拖动 bind 到 UI widget | Y1 只支持 BindingInspector 配置;Y2 考虑跨画布直接拖放(继承 DQ-09) |
10.2.1 Signal Flow 相关风险(⭐ 新增)
| 风险 | 缓解 |
|---|---|
| control-bus 与 audio-bus 时序不同步 | 后端 SignalBusService 用独立 task · 算法 Process 内原子读取 · 详见 D3-FE-ARCH-001 §5.8.4 |
| CAN 信号断线导致链路崩溃 | fallbackToDefault: true 默认启用 · BindingResolver 检测 quality=stale\|error 走 fallback |
| 大量 bindings(>100)导致 SetParam 队列拥堵 | 后端批量 10ms 窗口聚合 · DSP 侧双缓冲写入 binding_table |
10.2 继承的 DQ(顶层)
- DQ-02(Electron 桌面壳)/ DQ-06(Monorepo 位置)/ DQ-07(ai-sdk 契约)
10.3 风险
| 风险 | 缓解 |
|---|---|
| MC 链路格式不兼容新 LinkModel | PLAN-003 先定 LinkModel schema 并提供从旧格式迁移的工具函数 |
| XiForge 内嵌导致 Bundle 膨胀 | 用动态 import 做懒加载;Forge 路由独立 chunk |
| 多工程并发编译导致后端压力 | 前端排队(单用户最多 1 个在编译)+ 后端任务队列 |
11. 与 v1.0 版本的差异
| 维度 | v1.0(2026 早期) | v2.0(本文) |
|---|---|---|
| 架构 | .NET 8 + Electron 桌面 | Vue 3 web + Monorepo · Y2 评估 Electron |
| 路由 | 单体 appMode 切换 | vue-router 4 标准路由 |
| UI 层 | 自研组件 | @xi/ui-kit 统一 |
| 与其他产品的关系 | 独立 | Shell + 内嵌 Forge/VST + deep-link 呼起其他 |
| AI | 未集成 | @xi/ai-sdk 常驻 Copilot |
| 数据模型 | 独立 linkStore | @xi/store-core 的 LinkModel |
迁移策略:v1.0 代码不做兼容,按 D3-FE-PLAN-004 全新实现;现有 frontend_vue3/ 保留 6 个月只读兜底(见顶层架构 DQ-06)。
12. 版本与变更记录
| 版本 | 日期 | 作者 | 说明 |
|---|---|---|---|
| v1.0 | 2026-Q1 | (原作者) | 初稿 · .NET 8 + Electron 方向 |
| v2.0 | 2026-05-08 | work-cline | 重写 · Monorepo Shell + Vue 3 纯 web + Link Editor(MC 迁移)+ 内嵌 Forge/VST + AI Copilot 集成 |
| v2.1 | 2026-05-08 | work-cline | 用户反馈迭代:§1.3 新增车载系统集成工程师画像 + §1.4 竞品对标章节(AudioWeaver / SigmaStudio / LiveAmp 首选)+ §2.2 Mermaid 图补 SignalFlow 路由 + §3 目录加 signal-flow/ 组件 + SignalFlowView + useSignalFlowStore + §4.8 Signal Flow Editor 完整模块(对标 LiveAmp)+ §5 路由树补 /signal + §6.3 useSignalFlowStore 核心 API + §7.2 WebSocket 补 Signal I/O 消息 + §10 DQ-STUDIO-04 + §10.2.1 Signal Flow 风险 |
附录 A · 引用
- D3-FE-ARCH-001 顶层架构
- D3-FE-ARCH-002 文档规划
- D3-FE-ARCH-003 共享 UI kit 架构
- D3-FE-ARCH-004 实现 plan 总纲
- D2-P9 XiForge tech-arch(本轮产出 · 内嵌对端)
- D2-P6 XiTune tech-arch(本轮产出 · deep-link 呼起对象)