Phase 0 · 基线对齐 + 协议改造设计
目标:建立"v4.3 demo 协议契约"→"frontend_vue3 Pinia + EventBus 实现"的完整对照表,作为后续 Phase 1-17 的统一接口规约。
工作量:1 工作日 · 依赖:无 · 后置 phase:1-17(全部依赖本 phase 的协议契约)
1. 目标(一句话)
把 v4.3 demo 中的 12 类 postMessage 协议完整、无遗漏、语义保留地映射到 frontend_vue3 的 Pinia store action + EventBus event,并产出 TS 类型定义文件,让后续每个 phase 都能精确引用。
2. 前置条件
- ✅ frontend_vue3 项目结构已就绪(subagent 调研确认)
- ✅ Shell 容器组件树已搭建(XiStudioShell + 9 子组件)
- ✅ codex.css 已接入
- ✅ Pinia + persistedstate 已配置
- ✅ v4.3 demo 协议清单已锁定(详见
v1.2-ide-architecture.md §13)
3. 任务清单
3.1 子任务 T0.1 · 当前 frontend_vue3 完整基线快照(0.25d)
扫描并记录:
-
src/components/shell/全部 .vue 文件列表 + 每个文件的核心 props/emits/slots 摘要 -
src/stages/{xilink,xitune,xiforge,xitest}/入口文件结构(已实现 vs 占位) -
src/stores/现有 store 列表 + state 字段 + action 列表 -
src/composables/现有 composable 列表 + 用途 -
src/types/现有 TS 类型定义(特别是communication.ts完整 10 类 CommandType) -
src/api/或 WebSocket 客户端实现位置 -
e2e/现有 4 个 spec 的 describe 块清单 + 测试覆盖范围 -
package.json依赖列表(确认 mitt / pinia-plugin-persistedstate / vitest / playwright 都在)
产出:docs/08-implementation/30-frontend-vue3/00-baseline-snapshot.json(结构化数据 · 后续 phase 引用)
3.2 子任务 T0.2 · 协议改造对照表定稿(0.25d)
基于 00-master-plan.md §3.1 的草表,逐条审查 + 锁定:
| v4.3 原 postMessage 类型 | 方向 | 改造方案 | 实现位置 | 优先级 |
|---|---|---|---|---|
stage-ready |
↑ | useStageReady() composable + 路由 onMounted |
src/composables/useStageReady.ts |
P1 |
toolbar-inject |
↓ | useTopbarStore.setToolbar(buttons) |
src/stores/topbar.ts |
P1 |
toolbar-click |
↑ | EventBus toolbar:click |
src/utils/eventBus.ts |
P1 |
mode-switcher-inject |
↓ | useTopbarStore.setModes(chips, activeKey) |
同上 | P1 |
mode-switch-click |
↑ | EventBus mode-switch:click |
同上 | P1 |
engine-control |
↑ | useEngineStore.toggle/start/stop/restart |
src/stores/engine.ts |
P1 |
engine-state-changed |
→ | useEngineStore.state reactive |
同上 | P1 |
dock-inject |
↓ | useDockStore.setLeft/setRight |
src/stores/dock.ts |
P2 |
inspector-inject |
↓ | useInspectorStore.setHtml(html, module) |
src/stores/inspector.ts |
P2 |
module-properties-inject |
↓ | useBottomStore.setModuleHtml(html, module) |
src/stores/bottom.ts |
P2 |
select-node |
↑ | EventBus node:selected + useInspectorStore 联动 |
EventBus + store | P2 |
tuning-dialog |
↑ | EventBus dialog:open + useDialogStore.open() |
src/stores/dialog.ts |
P2 |
show-toast |
↑ | useToastStore.show(message, type?) |
src/stores/toast.ts |
P1 |
stage-status |
↓ | useStatusBarStore.setStageHtml(html) |
src/stores/statusbar.ts |
P2 |
stage-hint |
↓ | useBottomStore.setHint(html) |
同 bottom | P2 |
doc-tabs-inject |
↓ | useTopbarStore.setDocTabs(tabs, activeKey) |
同 topbar | P3 |
doc-tab-click/close/new |
↑ | EventBus doc-tab:{click/close/new} |
EventBus | P3 |
subtab |
↓ | 已被 doc-tab-click 取代 · 不实现 |
— | — |
符号说明:↑ = stage → shell · ↓ = shell → stage · → = shell 内部广播
3.3 子任务 T0.3 · TS 类型定义草案(0.25d)
新建 src/types/protocol.ts,包含全部协议数据契约:
// =====================================================================
// XiStudio v4.3 协议改造 · TS 类型定义
// 基于 v1.2-ide-architecture.md §13 锁定
// =====================================================================
export type StageKey = 'xilink' | 'xitune' | 'xiforge' | 'xitest'
// ---- Shell → Stage 类型(注入到 Pinia store) ----
export interface ToolbarButton {
id: string
icon?: string
label?: string
tip?: string
toggle?: boolean // v4.3 新增 · true 表示开关按钮(如引擎 ▶/■)
active?: boolean // 当前是否激活(仅普通按钮用 · toggle 按钮由 store 状态决定)
disabled?: boolean
}
export interface ModeChip {
key: string
icon?: string
label: string
tip?: string
disabled?: boolean // license add-on 未授权时灰显
}
export interface DocTab {
key: string
icon?: string
label: string
dirty?: boolean
}
export interface DockPane {
key: string
icon: string
tip: string
html?: string // legacy demo 形态 · Vue 路线下应改为 component 组件名 + props
component?: string // Vue 路线推荐 · component name registered globally
props?: Record<string, unknown>
}
// ---- 引擎状态 ----
export type EngineState = 'stopped' | 'running' | 'restarting' | 'error'
export interface EngineStateInfo {
state: EngineState
sampleRate?: number
bufferSize?: number
latencyMs?: number
}
// ---- EventBus 事件载荷 ----
export interface ToolbarClickPayload {
stage: StageKey
id: string
}
export interface ModeSwitchClickPayload {
stage: StageKey
key: string
}
export interface DocTabPayload {
stage: StageKey
key?: string // close / click 时必填 · new 时可选
}
export interface NodeSelectedPayload {
stage: StageKey
node: string
label: string
}
export interface DialogOpenPayload {
stage: StageKey
module: string
label: string
preset?: string // 可选 · 关联当前激活 preset
}
// ---- Toast / 通知 ----
export type ToastType = 'info' | 'success' | 'warning' | 'error'
export interface ToastMessage {
id: string
type: ToastType
message: string
duration?: number // ms · 默认 3000
}
新建 src/utils/eventBus.ts:
import mitt, { type Emitter } from 'mitt'
import type {
ToolbarClickPayload,
ModeSwitchClickPayload,
DocTabPayload,
NodeSelectedPayload,
DialogOpenPayload,
} from '@/types/protocol'
export type AppEvents = {
'toolbar:click': ToolbarClickPayload
'mode-switch:click': ModeSwitchClickPayload
'doc-tab:click': DocTabPayload
'doc-tab:close': DocTabPayload
'doc-tab:new': DocTabPayload
'node:selected': NodeSelectedPayload
'dialog:open': DialogOpenPayload
'engine:control': { stage: StageKey; action: 'start' | 'stop' | 'toggle' | 'restart' }
}
export const eventBus: Emitter<AppEvents> = mitt<AppEvents>()
3.4 子任务 T0.4 · Pinia store 骨架草案(0.25d)
新建 7 个核心 store 的骨架文件(仅 state + action 签名 · 实现留给后续 phase):
src/stores/topbar.ts
import { defineStore } from 'pinia'
import type { ToolbarButton, ModeChip, DocTab, StageKey } from '@/types/protocol'
export const useTopbarStore = defineStore('topbar', {
state: () => ({
// mode-switcher
modes: [] as ModeChip[],
activeMode: '' as string,
// stageToolbar
toolbar: [] as ToolbarButton[],
// doc-tabs (sub-tabs-bar)
docTabs: [] as DocTab[],
activeDocTab: '' as string,
}),
actions: {
setModes(chips: ModeChip[], activeKey?: string) {
this.modes = chips
this.activeMode = activeKey || chips[0]?.key || ''
},
setToolbar(buttons: ToolbarButton[]) {
this.toolbar = buttons
},
setDocTabs(tabs: DocTab[], activeKey?: string) {
this.docTabs = tabs
this.activeDocTab = activeKey || tabs[0]?.key || ''
},
clear() {
this.modes = []
this.activeMode = ''
this.toolbar = []
this.docTabs = []
this.activeDocTab = ''
},
},
})
src/stores/engine.ts
import { defineStore } from 'pinia'
import type { EngineState } from '@/types/protocol'
export const useEngineStore = defineStore('engine', {
state: () => ({
state: 'stopped' as EngineState,
sampleRate: 48000,
bufferSize: 256,
latencyMs: 0,
}),
getters: {
running: (s) => s.state === 'running',
},
actions: {
toggle() {
this.state = this.running ? 'stopped' : 'running'
},
start() { this.state = 'running' },
stop() { this.state = 'stopped' },
restart() {
this.state = 'restarting'
setTimeout(() => { this.state = 'running' }, 500)
},
},
// 不持久化 · 引擎运行状态是会话级
})
其余 5 个 store 骨架(dock / inspector / bottom / dialog / toast / statusbar)
详细签名见 00-master-plan.md §3.3。
业务级 store(project / profile / preset / test)留待 Phase 8/9/14/15 实现。
4. 接口契约
4.1 与现有 src/types/communication.ts(WebSocket 10 类命令)的关系
两套协议并存且互不冲突:
communication.ts= 前端 ↔ ASP.NET Core 8 后端的 WebSocket 命令(set_param/write_link/start_audio_engine等)protocol.ts(新建) = 前端内部 Shell ↔ Stage 的同进程通信契约(取代 v4.3 demo 的 postMessage)
调用流向示例(▶ 按钮):
[用户点击 ▶ 按钮(StageBar 组件)]
↓
[Vue @click → useEngineStore.toggle()]
↓
[engine store · state = 'running']
↓ watch
[useWebSocket.send({type: 'start_audio_engine', link, durationSec})] ← 走 communication.ts 协议
↓
[ASP.NET Core 8 后端启动 AudioEngine]
↓
[后端 broadcast set_param 等 → WebSocket 接收 → Pinia store 更新]
↓
[Sink RMS Dock ECharts 重渲]
4.2 license 守卫预留位
虽然 license 系统不在 Phase 0 范围内,但 store 设计要预留:
useTopbarStore.modes中的ModeChip.disabled字段 → 后续 license add-on 联动useTopbarStore.toolbar中的ToolbarButton.disabled字段 → 同上- 4 Stage Pill 的渲染逻辑:
useLicenseStore.canEnter(stage)(Phase 17 前接入)
5. 验收标准
| 维度 | 标准 |
|---|---|
| 完整性 | 18 类 protocol 项全部有改造方案落地(2 类合并:subtab 被 doc-tab-click 取代) |
| TS 严格 | src/types/protocol.ts 编译无 any · 所有 store action 签名带类型 |
| 基线快照存档 | 00-baseline-snapshot.json 写入仓库,记录 Phase 0 时刻所有关键文件清单与字段 |
| 文档可执行 | 后续 phase 文档可直接引用本 phase 的改造对照表,无需重新解释协议含义 |
| 代码骨架就位 | src/types/protocol.ts + src/utils/eventBus.ts + 7 个 store 骨架文件已 commit(feat(p0): protocol scaffolding) |
6. 验收脚本
6.1 手动验证
# 1. 类型检查通过
cd 04_development/frontend_vue3
npx tsc --noEmit
# 2. 单元测试启动 OK
npx vitest run --config vitest.config.ts test/unit/
# 3. Dev server 启动无报错
npm run dev
# 浏览器打开 http://localhost:3000 · 确认 Shell 容器渲染 + 4 Pill 可见
6.2 自动 e2e(暂不新增 spec · 沿用 4 个现有 spec 跑通即可)
7. 风险与回滚点
| 风险 | 缓解 |
|---|---|
现有 useLayoutStore 字段与新 store 重名 |
T0.1 扫描时确认无 namespace 冲突;如有冲突,在新 store 名前加 useTopbar* 等具体前缀 |
| mitt 包未安装 | T0.4 时 npm install mitt |
| 后续 phase 发现协议遗漏 | 任何 phase 发现新需求时,回到本文档新增条目 + 升 v1.1 |
回滚:本 phase 的改动全部限定在 src/types/ + src/utils/ + src/stores/,不修改任何 .vue 组件 · 全部回滚只需 git revert 单个 commit。
8. 关联文档
- 上层契约:
v1.2-ide-architecture.md §13 - 总计划:
00-master-plan.md - v4.3 demo 实现参考:
layout-demo/index.html - 后端通道(不冲突):master
AlgoDepartment/05_system_integration/SYSTEM_ARCHITECTURE.md - 后续 phase:所有 Phase 1-17 的"接口契约"章节都引用本文档 §3.2-§3.4
Phase 0 · 基线对齐 v1.0 · 2026-05-19 · 1 工作日 · 产出 4 类骨架文件 + 1 份基线快照 + 1 份对照表锁定