XiStudio Workspace 架构提案 v1.1
变更摘要(v1.0 → v1.1): 1. 新增
.xiprofile文件类型(7 后缀方案) — 响应用户:"管理 preset 的 profile · 类似 manifest" 2. 修正refresh_link语义 — 用户澄清:"已固化在 dsp 中可读取链路结构 · 确认是否符合预期"(校验/对账语义)· pc_simulation + target_live 都可用 · legacy_compat / auto_inverse 除外 3. 第 5 份 subagent 真值调研:Profile 系统现状(AmbianceProfile@xitune/ProfileSidebar.vue· 1046 行 · 1:N 引用 preset · 依附 link) 4. status: draft → decided(用户已拍板"决议都按你的建议来 · 启动 ADR")本文目的:为 XiStudio 4 stage 设计统一的 workspace 文件格式 + 项目组织 + stage 间数据流模型,响应用户提出的 5 个真实需求(文件后缀识别性 / XiForge 独立 / XiLink ↔ XiTune 关系 / 第三方插件 / 4 种调音模式)。
不是 PROMPT · 不是 ADR · 是决策前的可行性研究 + 推荐方案(类同 XiForge-Architecture-Proposal v1.0)。
0. 用户提出的核心问题(原话精简)
0.1 第一轮(2026-05-26 上午)
"各个 workspace 的文件格式问题 · 目前看起来 XiForge 是靠读取 json 来实现 · 但是如果我 workspace 下 link.json 由 preset.json 那当前是怎么区分文件是一个问题"
"整体上看 · 现在 4 个 stage 中 workspace 中如何划分 json 文件是一个需要考虑的问题"
"建议:文件后缀需要有识别性,比如
*.xilink*.xiforge*.xitest*.xitune· 其中 xiforge xitest 的文件应该是不和其他 workspace 耦合的 · xilink 和 xitune 要梳理一下关系"
0.2 第二轮关键澄清(2026-05-26 上午晚)
0.2.1 XiForge 生命周期短 + 第三方插件
"XiForge 其实实际产品使用周期是很短的 · 一旦 module 的壳子创建好之后 · 这个工程界面基本就很少用到了 · 所以后续可能会将这个 stage 放在菜单栏中"
"第三方 xivst 插件导入的问题 · AWE 的做法是将第三方算法的产物以目录管理的方式保存起来 · 本地在加载 xilink 插件的时候会去寻找是否有新加插件"
"我们的做法可能就是导出 vst 插件就是要么上传云端 · 后台统一管理 license 然后发布 · 要么是本地导入 · 其实就是把 lib/dll 源码文件 xiforge 的 json 文件复制到后台对应的位置"
0.2.2 XiLink ↔ XiTune 的 4 种调音模式(关键!)
"a) 正向开发,算法团队先行,搭建 link,调试集成没问题后,释放 xitune 工程给调音师,调音师不能修改 link,此时调音师可以做两种行为: i) 试车 DSP 上进行调音 · link 已经固化 · 此时可以不发 link · 也可以刷新 link · 但目的是 link 里面所有的 module 都能实时调音 ii) PC 模拟调音 · 后端和算法都在 PC 运行 · 来模拟实际的调音参数的理论行为 · 那此时肯定需要发 link · 因为后端不会固化任何 link 参数"
"b) 兼容模式:底层算法完全没有 link 实现 · 链路只是象征意味的底层算法排列 · 目的就是每个 module 的调音参数可以实时更新的 DSP 算法 · 不涉及链路重构"
"c) 反向调音:通过声学信号反向实现算法 · 计算出需要的曲线和需要的算法 · 自动搭建一套 link 链路和 preset"
1. 当前真值盘点(基于 2 份代码调研)
1.1 已有的扎实基础
| 项 | 真值 | 评估 |
|---|---|---|
| 2 个 workspace store | workspaceStore.ts(主工程 · 228 行) + xiForgeWorkspaceStore.ts(IP 工程) |
✅ 已有结构 |
| 行为后端化 | 全部走 WS 协议(set_workspace / set_xiforge_workspace) |
✅ 协议层就绪 |
| 发 link 协议 | write_link(主推 · 4 处触发) + apply_link(结构性参数变更) |
✅ 双协议齐全 |
| 文件保存 | MenuBar.vue 的 exportProject · 用 Blob + a[download](经典模式) |
✅ 已实现 |
| linkStore | 含 nodes/edges/instances + 画布 viewport | ✅ 数据结构完整 |
| presetStore | 168 行 CRUD 已就绪 | ✅ 可扩展 |
1.2 关键空白(必须新建)
| 缺失项 | 需要的场景 | 优先级 |
|---|---|---|
| 文件后缀识别 | 全部为 .json · 无 .xilink/.xiforge/.xitune/.xitest 区分 |
P0(用户必须) |
| 统一项目目录概念 | 当前是"workspace 根 + 多 project 子目录" · 但每个 project 内部没有 stage 文件分类 | P0 |
refresh_link 协议(从 DSP 反读) |
场景 2a-i 试车 DSP 调音 · 当前只有 read_link 用于测试 |
P0 |
| TuningMode 4 种区分 | 场景 2a-i / 2a-ii / 2b / 2c | P0(产品级核心) |
| linkStore draft/deployed 双状态 | 场景 2a-i 必需("DSP 已固化" vs "用户编辑草稿") | P1 |
| 反向调音占位 | 场景 2c | P3(长期) |
| 第三方 VST 插件机制 | 用户场景 1 延伸 | P3(长期) |
2. 业界对标精华(2 份 subagent 报告综合)
2.1 项目文件组织模式 4 选 1
| 模式 | 代表产品 | 适用 XiStudio? |
|---|---|---|
| A · 项目目录 | Logic Pro X / IntelliJ / Reaper | ✅ 推荐(用户拍板 1A) |
| B · 单文件容器(zip) | Ableton .als / Figma .fig |
⚠️ 不利于 git 管理 |
| C · 主文件 + sidecar | Cubase .cpr + Audio/ |
⚠️ 多一层 manifest |
| D · 纯独立文件 | VSCode .code-workspace |
❌ 无法表达跨 stage 关联 |
2.2 AWE 关键启发(第三方插件 + Tuning Mode)
- AWE Module Library 用目录扫描 + 元数据注册(非 Windows 注册表) · 启动时聚合
- AWE Tuning Mode vs Standalone Mode 直接对应用户场景 2a-ii vs 2a-i
- AWE
awe_pumpAudioPreset是单向 push(host → target) · 但 Tuning Mode 也支持从 target 读回当前 preset 状态(回读)
2.3 VST3 Preset 启示
- VST3 用独立
.vstpreset· 跨 plugin 不通用(ClassID 绑定) - DAW 保存工程时把 preset 序列化为 chunk 内嵌
- Preset 永远独立文件 + 工程时可内嵌(给 XiStudio 的强烈启示)
3. 核心架构设计(本提案推荐)
3.1 文件后缀体系(决议 1 · v1.1 扩展为 7 种)
*.xistudio ← 项目主清单文件(轻量 manifest · JSON)
*.xilink ← 链路定义(XiLink stage 输出)
*.xitune ← 调音工程(XiTune stage 输出 · 单一调音状态 · 引用 .xilink)
*.xitest ← 测试用例集(XiTest stage 输出 · 独立)
*.xiforge ← 模块定义(XiForge stage 输出 · 独立 · 可放后台目录)
*.xipreset ← Preset 单文件(独立 · 单模块参数集 · 可跨工程复用 · 类 .vstpreset)
*.xiprofile ← Profile 文件(v1.1 新增 · 多 preset 组合方案 · 依附 .xilink)⭐
为什么这样设计:
- 7 种后缀全部以 .xi 开头 · 系统视觉识别一致 · 避免与已知后缀冲突
- 实际 schema 可以是 JSON · 但不带 .json 子后缀(不要 .xilink.json · 太啰嗦)
- 文件类型关联可以让用户双击 .xistudio 直接打开整个项目
.xiprofile vs .xipreset vs .xitune 三者层次:
| 文件 | 粒度 | 含什么 | 依附性 | 类比 |
|---|---|---|---|---|
.xipreset |
单模块 · 单参数集 | 一个 module 的所有参数值 | 不依附 link · 只依附 ModuleDef.uid | VST3 .vstpreset |
.xiprofile |
多模块组合 · 场景方案 | "modulePresets: {instanceId → presetId}" 映射 | 依附 .xilink(因为 key 是 instanceId) | DAW Channel Strip Preset / Track Template |
.xitune |
完整调音状态 · 工程级 | tuningMode + linkRef + 当前 profileRef + paramOverrides | 依附 .xilink + 引用 .xiprofile/.xipreset | Logic Pro Project File |
3.2 项目目录结构(决议 2 · 用户拍板 1A)
3.2.1 推荐结构(v1.1 · 新增 profiles/ 目录)
my-amplifier-project/ ← 项目根目录(用户在 XiStudio 中"打开")
├── my-amplifier.xistudio ← 项目清单(轻量 manifest · 入口)
├── link/
│ └── main.xilink ← 链路定义
├── tuning/
│ ├── default.xitune ← 默认调音工程(引用 ./link/main.xilink + ./profiles/xxx.xiprofile)
│ └── tuner-a.xitune ← 调音师版本
├── profiles/ ← ⭐ v1.1 新增 · Profile 库(多 preset 场景方案)
│ ├── jazz-scenario.xiprofile ← 引用本项目 link 的 instanceId 集合
│ ├── classical-scenario.xiprofile
│ └── movie-scenario.xiprofile
├── presets/ ← 独立 preset 库(单模块参数集 · 可跨工程导入)
│ ├── eq-jazz-warm.xipreset ← 单 module preset
│ ├── eq-classical-bright.xipreset
│ ├── compressor-soft.xipreset
│ └── reverb-hall.xipreset
├── tests/
│ ├── smoke.xitest
│ ├── electrical.xitest
│ └── acoustic.xitest
└── assets/ ← 资源文件(可选)
├── target-curves/
│ └── flat-response.csv
└── reference-audio/
└── pink-noise.wav
目录语义:
- presets/ — 跨项目可复用的单模块参数(类 VST3 plugin preset library)
- profiles/ — 依附本项目 link的多模块组合方案(类 DAW Channel Strip Preset · 用户切场景:jazz/classical/movie)
- 用户在 XiTune 切 profile = 一键改 N 个模块的 preset 选择(快速场景切换)
3.2.2 关键设计
*.xistudiomanifest 内容(v1.1 · 新增 profile_library):{ "version": "1.0", "name": "My Amplifier Project", "uid": "0xC0FFEE12345", "created": "2026-05-26", "stages": { "link": "./link/main.xilink", "tuning": "./tuning/default.xitune", "tests": ["./tests/smoke.xitest", "./tests/acoustic.xitest"] }, "preset_library": "./presets/", "profile_library": "./profiles/" }- stage 间引用:用相对路径(类 Pro Tools 工程文件引用 sibling
Audio Files/) .xiforge不在项目目录里:见 §3.3.xipreset既可在项目内presets/· 也可在全局库(类 VST 用户 plugin 路径).xiprofile在项目内profiles/(因为依附本项目 link 的 instanceId · 不跨项目)
3.3 XiForge 独立性 + 第三方插件管理(决议 3 · 响应用户场景 1)
3.3.1 双重存储位置(类 AWE)
~/Library/XiStudio/Modules/ ← 全局后台目录(类 AWE Module Library)
├── builtin/ ← XiStudio 内置模块(随版本发布)
│ ├── source/
│ │ ├── source_v1.xiforge
│ │ ├── source_sine_v1.xiforge
│ │ └── ...
│ ├── filter/
│ │ ├── geq_v1.xiforge
│ │ └── ...
│ └── ...
├── thirdparty/ ← 第三方 vst 插件目录(用户上传到此)
│ ├── acmecorp_compressor/
│ │ ├── manifest.xiforge ← 模块定义(JSON)
│ │ ├── compressor.dll ← 算法二进制(Windows)
│ │ ├── compressor.so ← 算法二进制(Linux)
│ │ └── compressor.c ← 源码(可选 · 用于 codegen)
│ └── studiomax_reverb/
│ └── ...
└── user-custom/ ← 用户在 XiForge 自建的模块
└── my-custom-eq.xiforge
3.3.2 加载机制(类 AWE 启动扫描)
XiStudio 启动时:
1. 扫描 ~/Library/XiStudio/Modules/builtin/ → 内置模块 → moduleDefStore
2. 扫描 ~/Library/XiStudio/Modules/thirdparty/ → 第三方模块 → moduleDefStore(标 vendor='xivst')
3. 扫描 ~/Library/XiStudio/Modules/user-custom/ → 用户自建模块 → moduleDefStore(标 vendor='xistudio', source='user')
4. 项目打开时,XiLink 加载 .xilink · 链路引用的所有 ModuleDef 都通过 UID(ADR-AIOS-04)从 moduleDefStore 解析
3.3.3 用户场景对应
| 用户原话场景 | 对应方案 |
|---|---|
| "上传云端 · 后台统一管理 license 然后发布" | Phase 2(下半年):云端 vendor registry · 用户从云端选择安装到 thirdparty/ |
| "本地导入 · 复制 lib/dll 源码 + xiforge json 到后台对应位置" | Phase 1(本季度):提供"导入 .xiforge 包"功能 · UI 选择 .zip 或目录 · 解压到 thirdparty/ |
| "XiForge 工程界面基本很少用到 · 放菜单栏中" | Phase 1:XiForge 不再是 4 stage 之一 · 改为菜单 "Tools → Module Builder" 或独立窗口 |
3.3.4 关键洞察:XiForge 与项目工程完全独立
- XiForge 输出的
.xiforge文件 = 模块产物(像 AWE 的 awm 文件 / VST 的 plugin) .xiforge不在项目目录中 · 在全局后台库中- 项目(
.xilink)只通过 ModuleDef.uid(ADR-AIOS-04 的 32 位 UID)引用模块 - 这彻底解决了用户问的"XiForge 不和其他 workspace 耦合"的问题
3.4 XiLink ↔ XiTune 关系(决议 4 · 4 种调音模式)
用户场景 2 是整个 XiStudio 最核心的产品差异化。需要超越简单的"读/写 link"二元模型 · 设计 4 种调音模式。
3.4.1 4 种调音模式定义(灵感来自 AWE Tuning Mode + VST Bypass/Active/Freeze)
export type TuningMode =
| 'pc_simulation' // 场景 2a-ii · PC 模拟 · 后端在 PC 运行 · 必须发 link
| 'target_live' // 场景 2a-i · 试车 DSP · link 已固化在 DSP · 仅参数实时调
| 'legacy_compat' // 场景 2b · 兼容模式 · 链路象征 · 仅 PID 调参
| 'auto_inverse' // 场景 2c · 反向调音 · 算法生成 link + preset(实验性)
3.4.2 4 种模式的数据流对照
═══════════════════════════════════════════════════════════════════════
模式 1 · pc_simulation(场景 2a-ii)
═══════════════════════════════════════════════════════════════════════
用户在 XiTune 修改参数
↓
linkStore (host PC · 完整 link)
↓ write_link / apply_link / set_params
后端 PC 模拟引擎(DSP 模拟器)
↓ 输出模拟音频
用户听音
特点:
- link 必须发(每次结构变更)
- 参数实时双向(host ↔ PC backend)
- linkStore 是 SSOT
- 适合产品化前的算法开发期
═══════════════════════════════════════════════════════════════════════
模式 2 · target_live(场景 2a-i)
═══════════════════════════════════════════════════════════════════════
DSP 设备(target board)←━━ link 已固化 · 重启不丢失
↑ ↓ refresh_link(新协议 · 反读)
↓ set_params · linkStore (host · 只读链路视图 + 可编辑参数)
↓
用户调音(只调参数 · 不改链路)
特点:
- **不发 link**(DSP 上已固化)
- 但**可以"刷新 link"**(refresh_link 反读 DSP 当前链路状态 · 显示给用户)
- 参数双向(host ↔ DSP)· 链路只读(host 显示 · 不能改结构)
- linkStore 区分 deployedLinkSnapshot(只读 · 来自 DSP)+ paramOverrides(可写)
- 适合产品发布后的调音期 · 调音师不能误改链路
═══════════════════════════════════════════════════════════════════════
模式 3 · legacy_compat(场景 2b)
═══════════════════════════════════════════════════════════════════════
DSP 设备(legacy 固件)
↑ legacy_set_param + PID
linkStore = 仅符号占位(几个 module 卡片 · 不组成连线)
↑ 用户调参
XiTune dialog
特点:
- 链路是装饰性的(showcase 用)
- 协议走 PID(不是 paramId)
- link 既不发也不读(因为没意义)
- 对应 ADR-AIOS-04 决议 9 · ModuleDef.mode = 'legacy'
- 适合接入旧 DSP 固件无法升级的客户
═══════════════════════════════════════════════════════════════════════
模式 4 · auto_inverse(场景 2c · 实验性)
═══════════════════════════════════════════════════════════════════════
声学测量信号(参考曲线 / 实测响应)
↓
反向算法(后端运行 · 优化器)
↓ 自动生成
候选 link draft + 候选 preset draft
↓ 用户审核
应用到 linkStore.deployed
特点:
- 数据流向反转(声学输入 → 算法 → link 输出)
- 必须有"draft 草稿态"让用户预览 + 微调
- 应用前必须有 confirm 步骤
- 长期路线 · 本季度仅占位(P3 优先级)
3.4.3 linkStore 双状态扩展(支持 target_live 模式)
// 当前(单状态)
interface LinkState {
nodes: Node[]
edges: Edge[]
instances: Instance[]
}
// 新设计(双状态)
interface LinkState {
// 编辑态(host 草稿 · 用户在 XiLink 改的就是这个)
draft: {
nodes: Node[]
edges: Edge[]
instances: Instance[]
}
// 部署态(DSP 实际运行的 · 通过 refresh_link 反读得到)
deployed?: {
nodes: Node[]
edges: Edge[]
instances: Instance[]
syncedAt: string // 上次刷新时间
source: 'pc_backend' | 'target' // 来自哪里
}
// 在 target_live 模式下 · UI 显示 deployed · 不允许编辑结构 · 只允许改参数
}
3.4.4 XiLink ↔ XiTune 数据共享策略(综合 · v1.1 修正 refresh_link 语义)
| 调音模式 | XiTune 加载策略 | linkStore 内容来源 | refresh_link 用途 |
|---|---|---|---|
| pc_simulation | 加载同项目 .xilink(读+写) |
linkStore.draft = .xilink | ⭐ 校验/对账(确认 PC backend 加载的 link 与 host 一致) |
| target_live | 启动 refresh_link 协议 |
linkStore.deployed = DSP 反读 · linkStore.draft 不可编辑 | ⭐ 校验链路(确认 DSP 固化的 link 是否符合预期) |
| legacy_compat | 不加载 .xilink(因为 legacy 模块通常无项目级 link) | linkStore = 仅装饰性占位 | ❌ 不适用(无真实 link) |
| auto_inverse | 算法生成新 link → linkStore.draft | linkStore.draft = 算法输出 · 应用后写回 .xilink | ❌ 不适用(数据流反向) |
3.4.5 ⭐ refresh_link 语义校准(v1.1 · 用户澄清)
用户原话:"已经固化在 dsp 的调音场景中,是可以在 dsp 中读取当前链路结构的,用来确认链路是否如符合预期"
refresh_link 协议有 2 种语义(v1.1 修正):
- 加载时反读(target_live 模式专用):
- 打开
.xitune· 模式为 target_live → 自动调用refresh_link从 DSP 反读链路结构 → 填充 linkStore.deployed -
用户看到 DSP 实际固化的链路(只读)+ 可调音的参数
-
校验/对账(pc_simulation + target_live 都可触发):
- 用户主动点 "刷新链路" 按钮 →
refresh_link反读 → 与 host 当前 linkStore 比较 → 显示差异(missing modules / param drift / connection mismatch) - 用途:确认 DSP / PC backend 加载的 link 与 host 工程一致(对账机制)
- legacy_compat / auto_inverse 不适用(legacy 无真实 link · auto_inverse 数据流反向)
回应用户原始问题(选项 A/B/C): - 我之前推荐选项 C(只读按需) · 但用户场景揭示不够用 - 真正的方案是 C+扩展:基础是只读按需(target_live 反读) · 但加上 PC 模拟时的双向 · 反向调音时的草稿态 · 加上所有非 legacy/non-inverse 模式都可用 refresh_link 做校验 - 即:多模式数据流 + 通用校验机制(由 TuningMode 决定数据流方向 · refresh_link 跨 2 种正常模式可用)
3.5 Preset / Profile 文件设计(决议 5 · v1.1 扩展)
3.5.1 三层架构(类 VST3 + DAW Channel Strip)
┌──────────────────────────────────────────────────────────┐
│ .xitune(完整调音状态 · 工程级) │
│ ├ tuningMode: 'pc_simulation' / 'target_live' / ... │
│ ├ linkRef: '../link/main.xilink' │
│ ├ activeProfileRef?: '../profiles/jazz-scenario.xiprofile' │
│ └ paramOverrides: { ... }(临时调音 · 未保存的微调) │
└──────────────────────────────────────────────────────────┘
↓ 引用
┌──────────────────────────────────────────────────────────┐
│ .xiprofile(场景方案 · 多模块组合) │
│ ├ name: "Jazz Scenario" │
│ ├ icon: "🎷" │
│ ├ scenario?: "jazz" / "classical" / "movie" │
│ ├ linkRef: '../link/main.xilink'(依附此 link) │
│ └ modulePresets: { │
│ "instanceId-0xC0FFEE0001": "../presets/eq-jazz.xipreset", │
│ "instanceId-0xC0FFEE0002": "../presets/comp-soft.xipreset" │
│ } │
└──────────────────────────────────────────────────────────┘
↓ 引用
┌──────────────────────────────────────────────────────────┐
│ .xipreset(单模块参数集 · 跨项目可复用) │
│ ├ moduleUid: 0x00000200(filter/geq · ADR-AIOS-04) │
│ ├ name: "EQ Jazz Warm" │
│ └ params: { gain: 6.5, freq: 440, q: 1.2, ... } │
└──────────────────────────────────────────────────────────┘
3.5.2 .xiprofile schema(v1.1 新增)
基于 subagent 真值调研(AmbianceProfile @ types/module.ts:222),新增 metadata 字段:
// jazz-scenario.xiprofile
{
"version": "1.0",
"profileId": "uuid-xxxx",
"name": "Jazz Scenario",
"icon": "🎷",
"scenario": "jazz", // ⭐ v1.1 新增 · 业务标签
"linkRef": "../link/main.xilink", // ⭐ v1.1 新增 · 依附性
"linkUid": "0xC0FFEE12345", // ⭐ v1.1 新增 · 双重校验(防 link 被替换后 instanceId 失效)
"createdAt": "2026-05-26T10:25:00Z", // ⭐ v1.1 新增
"modulePresets": {
"instance-0xC0FFEE0001": "../presets/eq-jazz.xipreset",
"instance-0xC0FFEE0002": "../presets/comp-soft.xipreset",
"instance-0xC0FFEE0003": "../presets/reverb-hall.xipreset"
}
}
关键设计:
- linkRef + linkUid 双重校验:加载 .xiprofile 时验证 link 没被替换(instanceId 一致性)
- scenario 字段:为 UI 提供分类(快速筛选 jazz / classical / movie)
- modulePresets 引用 .xipreset(而不是内嵌参数) — Profile 是"组合方案" · 不持有 preset 实参
3.5.3 .xipreset schema(规范化)
// eq-jazz-warm.xipreset
{
"version": "1.0",
"presetId": "uuid-yyyy",
"name": "EQ Jazz Warm",
"moduleUid": "0x00000200", // ⭐ ADR-AIOS-04 UID 引用
"moduleVendor": "xistudio",
"moduleVersion": "1.0.0", // 兼容性校验
"createdAt": "2026-05-26T10:25:00Z",
"params": {
"gain": 6.5,
"freq_band1": 440,
"q_band1": 1.2,
"type_band1": "peaking"
},
"tags": ["jazz", "warm", "low-mid-boost"] // 可选 · 搜索/筛选用
}
3.5.4 Preset/Profile 自动派生(承接 ADR-AIOS-04 决议 2)
- Preset Schema = ModuleDef.params 自动派生(不需要用户写 schema)
- Preset 实例值 = 用户在 XiTune 调出来后保存为
.xipreset - Profile = 用户在 XiTune 切换 N 个 preset 后,"另存为 Profile" 生成
.xiprofile(只存映射 · 不存参数)
3.5.5 用户工作流
[ XiTune · 用户在调音 ]
↓ 调好 EQ 模块的参数
[ "另存为 Preset" ] → eq-jazz-warm.xipreset(单模块)
↓ 调好其他模块 · 多次保存 preset
[ "另存为 Profile" ] → jazz-scenario.xiprofile(组合方案 · 引用上面 N 个 preset)
↓ 切换场景
[ 加载 Profile "Classical Scenario" ] → 一键改 N 个模块的 preset 选择
3.6 文件保存/加载 API(决议 6)
3.6.1 保存方案
由于 XiStudio 当前已通过 WS 协议把 workspace 行为后端化(set_workspace 等),保存推荐:
- 小文件直接走 WS 协议(
.xilink/.xitune/.xipreset通常 < 1MB) - 后端文件系统读写
- 不依赖浏览器 API
- 可与 git 集成
- 批量导出 / 备份用 Blob + a[download](已有实现)
- 不用浏览器 File System Access API(实验性 · Chrome only)
3.6.2 协议消息扩展
// 新增 WS 消息类型
type WorkspaceProtocol =
| { type: 'open_project'; path: string }
| { type: 'save_xilink'; path: string; data: XiLinkData }
| { type: 'save_xitune'; path: string; data: XiTuneData }
| { type: 'save_xitest'; path: string; data: XiTestData }
| { type: 'save_xipreset'; path: string; data: PresetData }
| { type: 'export_xistudio_manifest'; path: string } // 导出 .xistudio 项目清单
| { type: 'refresh_link'; ... } // 新增 · 从 DSP 反读
| { type: 'list_modules'; scope: 'builtin' | 'thirdparty' | 'user-custom' } // 第三方插件扫描
4. 实施优先级路线图(v1.1 · 新增 .xiprofile 任务)
| 优先级 | 任务 | 工作量 | 阶段 | 依赖 |
|---|---|---|---|---|
| P0 | 7 后缀文件体系 + .xistudio manifest 设计 + 5 种 stage 文件类型定义 |
1d | 本季度 | 无 |
| P0 | 项目目录结构(含 profiles/) + workspaceStore 升级支持 manifest | 1.5d | 本季度 | P0 类型 |
| P0 | TuningMode 枚举 + linkStore draft/deployed 双状态 | 1.5d | 本季度 | 无(独立) |
| P0 | refresh_link 协议(双语义:反读 + 校验)+ 后端配合 |
2d | 本季度 | 后端 ClaudeB 协调 |
| P1 | XiTune 4 模式 UI 切换 + dialog 改造 + 校验差异 UI | 2d | 本季度 | P0 TuningMode |
| P1 | Preset 独立文件 .xipreset 保存/加载(类 VST3) |
1d | 本季度 | P0 文件后缀 |
| P1 | ⭐ Profile 独立文件 .xiprofile 保存/加载 + linkUid 双重校验 |
1d | 本季度 | P1 .xipreset |
| P2 | 第三方 vst 插件本地导入(类 AWE 目录扫描) | 2d | 下季度 | P0 后端目录扫描 |
| P2 | XiForge 移到菜单栏(从 4 stage 之一调整为 Tools 菜单) | 1d | 下季度 | 用户场景 1 |
| P3 | auto_inverse 反向调音占位(stub 框架) | 3d | 下下季度 | 算法预研 |
| P3 | XiVST 云端 vendor registry | 10d+ | 明年 | 商业化决策 |
Phase 1(P0 + P1) ≈ 10d · 单 agent 8-11 天完成 · 横跨 4 stage(需要协调 ClaudeA/B/C/D)
5. 决议拍板状态(v1.1 · 用户已全部确认)
2026-05-26 10:18 用户原话:"决议都按照你的建议来吧 · 启动 ADR"
决议 1 · 文件后缀体系 ✅ v1.1 扩展
- ☑ 7 后缀方案(.xistudio / .xilink / .xitune / .xitest / .xiforge / .xipreset / .xiprofile ⭐ v1.1 新增)
决议 2 · 项目目录结构 ✅
- ☑ 方案 A · 项目目录模式 + .xistudio manifest + profiles/ 子目录(v1.1)
决议 3 · XiForge 独立 + 第三方插件 ✅
- ☑
.xiforge在全局后台目录(~/Library/XiStudio/Modules/)· 不在项目目录 - ☑ 本季度做本地导入(P2)· 下半年云端 registry(P3)
- ☑ XiForge 从"4 stage 之一"演进为"菜单 + 独立窗口"
- ☑ 学 AWE 的目录扫描机制 + 命名分类
⭐ 决议 4 · 4 种调音模式 ✅(v1.1 修正 refresh_link 语义)
- ☑ 4 种 TuningMode:pc_simulation / target_live / legacy_compat / auto_inverse
- ☑ linkStore 扩展为 draft + deployed 双状态
- ☑
refresh_linkWS 协议 · 双语义(v1.1): - 加载时反读(target_live 自动)
- 校验/对账(pc_simulation + target_live 用户主动 · legacy/auto_inverse 不适用)
- ☑ XiTune UI 加 4 模式切换器
- ☑ auto_inverse 长期占位 · 本季度仅 stub(P3)
决议 5 · Preset / Profile 三层架构 ✅(v1.1 扩展)
- ☑
.xipreset独立文件(类 VST3 · 单模块参数 · 跨项目可复用) - ☑ ⭐
.xiprofile独立文件(v1.1 新增 · 多 preset 组合方案 · 依附 link) - ☑
.xitune引用.xiprofile+.xipreset(三层架构) - ☑ Preset Schema 自动派生(承接 ADR-AIOS-04 决议 2)
- ☑ Profile 引用 link 时双重校验(linkRef + linkUid)
决议 6 · 保存/加载 API ✅
- ☑ 小文件走 WS 协议(后端文件系统)· 与 git 友好
- ☑ 批量导出走 Blob + adownload
- ☐ 不用浏览器 File System Access API
决议 7 · 起 ADR-AIOS-05 ✅
- ☑ 本季度立即起 ADR-AIOS-05(用户原话:"启动 ADR")
6. 拍板后的下一步(v1.1)
人类已拍板(2026-05-26 10:18) · AIOS 立即执行:
- 起 ADR-AIOS-05 · 落盘
docs/08-implementation/40-aios/ADR/(立即执行) - 章节 1:7 后缀文件体系 + 项目目录结构(决议 1+2)
- 章节 2:4 种 TuningMode + linkStore 双状态(决议 4 · 核心)
- 章节 3:XiForge 独立 + 第三方插件目录(决议 3)
- 章节 4:Preset / Profile 三层架构(决议 5 · v1.1 扩展)
-
章节 5:WS 协议扩展(
refresh_link双语义 ·save_xiprofile等) -
更新 KANBAN.md v6 · 在 ClaudeA / ClaudeC 任务表加 P0/P1 任务
-
起草 6 份 PROMPT(v1.1 新增 .xiprofile · 共 6 份):
PROMPT-claudec-tuning-mode-system.md(P0 · 4 种调音模式 · 2.5d · ClaudeC 主)PROMPT-claudea-workspace-file-system.md(P0 · 7 后缀 + 项目目录 · 2.5d · ClaudeA 主)PROMPT-claudeb-refresh-link-protocol.md(P0 · 后端 ClaudeB · 双语义 · 2d)PROMPT-claudec-xipreset-xiprofile.md(P1 · ⭐ Preset+Profile 独立文件 · 2d)PROMPT-claudea-thirdparty-module-scanner.md(P2 · 下季度 · 2d)-
PROMPT-claudea-xiforge-menu-migration.md(P2 · 下季度 · 1d) -
后端 ClaudeB 协调:
refresh_link协议同步落地(必须前后端配合)
7. 调研真值参考(v1.1 · 累计 5 份 subagent 报告)
第一轮 · 代码真值(2 份 · 2026-05-26 09:00): - workspace 概念现状(2 个 store + 文件后缀 0 自定义 + 保存加载分布) - 协议层与反向调音真值(write_link 已有 / read_link 仅测试 / TuningMode 0 区分 / 反向调音 0 占位)
第二轮 · 业界对标(2 份 · 2026-05-26 09:30): - AWE 第三方算法管理(目录扫描 + 元数据注册)+ DAW 运行时模式(Tuning Mode 启发) - DSP 工具数据流方向(单向 push 主流 + 双向 sync 是高级特性)
第三轮 · Profile 系统(1 份 · v1.1 新增 · 2026-05-26 10:18):
- Profile 真值:AmbianceProfile @ xitune/ProfileSidebar.vue(1046 行) · 1:N 引用 preset · 依附 link · 与 preset 共用 store · 无独立持久化
调研基线 commit:8e7071b488a68135f6f995bc6eef18356c427c11
END · v1.1 提案 · status: decided · 用户已全部拍板 · 立即转 ADR-AIOS-05 + 6 份 PROMPT 落盘