ef93f9615f
新增模块:
src/queue.rs ── QueueStore(内存版)+ SongQueue trait + QueueItem/QueueState
src/downloader.rs ── yt-dlp 子进程下载到 data/cache/raw/<source>-<id>.<ext>
src/worker.rs ── 每房间 worker:resolve → download → transcode → deliver
src/event_loop.rs 改造:
- 构造 SearchFacade(包含 YtDlpBackend + 3 stub backend)
- 命令 handler 分发:
!help → render_reply + send_text
!req <q> → search_all → 自动取第一条入队(M7 接 reactions)
!req-url → 构造 candidate → 入队
!queue → 渲染队列状态
!np → 渲染当前播放
!skip → 弹出当前播放
- ensure_room_worker:首次收到消息时启动该房间 worker
- extract_video_id:支持 YouTube v= / youtu.be/ / B站 BV 号提取
src/main.rs:
- 引入 queue/downloader/worker 模块
CLAUDE.md 同步:
- 当前阶段改为 "M1-M5 已完成" + 已完成模块清单
- 列出已确认技术决策 11 条(不可变)
- 列出待办 M6-M7
E2EE 通道保持:
- 所有出站经 Timeline::send
- audio_upload.deliver() 内部仍走 TimelineBuilder + send
依赖决策(注意):
- 放弃 rusqlite(libsqlite3-sys 与 matrix-sdk-sqlite 链接冲突)
- 放弃 reqwest(用 yt-dlp 子进程下载,简化 deps)
- 队列改 in-memory(重启清空,v1 接受)
- 这两条记入 CLAUDE.md "已确认技术决策" 第 10、11 条
测试:cargo test → 24 passed + 4 ignored
新增 3 个 queue 测试:
- enqueue_and_dedup:同 song 同房间去重
- different_sources_not_dedup:不同 source_id 允许入队
- skip_current_returns_head:skip 弹出当前
133 lines
5.3 KiB
Markdown
133 lines
5.3 KiB
Markdown
# Matrix 点歌机器人 - 项目协作规范
|
||
|
||
## ⚠️ 核心协作要求(项目全程必须遵守)
|
||
|
||
### 1. 技术决策流程
|
||
|
||
在整个项目开发过程中,任何关于技术方面的事情,用户无法提供具体要求,必须遵循以下流程:
|
||
|
||
1. **列出方案**:对于每一个技术决策点(技术选型、架构设计、实现方式、依赖库选择等),我必须主动列出 **2 个或以上** 的可选方案
|
||
2. **解释方案**:对每个方案,需要详细说明:
|
||
- 该方案的具体内容
|
||
- 优缺点
|
||
- 适用场景
|
||
- 潜在风险
|
||
3. **等待决策**:在用户明确选择之前,**不得自行决定或默认选择任何一个方案**
|
||
4. **用户决定**:由用户拍板决定采用哪个方案,或要求更多方案
|
||
5. **记录决策**:用户选定后,再开始实施
|
||
|
||
### 2. Git 实时提交规范
|
||
|
||
**项目全程必须实时提交到 git**,禁止积累大批改动后一次性提交。具体要求:
|
||
|
||
- ✅ **每个独立的逻辑单元完成后立即提交**(单个文件完成、单个函数实现、单个 milestone 结束)
|
||
- ✅ **每个 milestone 结束后必须有可运行的 commit**(即使只是占位实现)
|
||
- ✅ **commit message 用中文**,按 Conventional Commits 风格(`feat:` / `fix:` / `docs:` / `chore:` / `refactor:` / `test:` / `style:`)
|
||
- ✅ **每次提交前确保 `cargo build` 或 `cargo check` 通过**(避免 broken commit)
|
||
- ✅ **重要决策点(用户已确认的方案)必须在 commit message 中体现**
|
||
|
||
**commit 粒度参考**:
|
||
|
||
```
|
||
docs: 初始化 CLAUDE.md 项目协作规范
|
||
docs: 添加 v1 实施计划
|
||
chore: 初始化 Cargo 项目骨架与依赖
|
||
feat(bootstrap): 实现 matrix-sdk login + 恢复登录
|
||
feat(client): 构造 matrix-sdk Client(双 db 文件 + E2EE settings)
|
||
feat(event_loop): 实现 Timeline 订阅与 !help 命令
|
||
...
|
||
```
|
||
|
||
---
|
||
|
||
## 适用范围
|
||
|
||
上述规则适用于项目中的**所有技术决策**,包括但不限于:
|
||
|
||
- 编程语言版本
|
||
- 框架与依赖库选择
|
||
- 数据库 / 存储方案
|
||
- 网络通信协议
|
||
- 加密与安全方案
|
||
- 项目目录结构
|
||
- API 设计
|
||
- 部署方式
|
||
- 测试方案
|
||
- 错误处理策略
|
||
- 日志方案
|
||
- 配置文件格式
|
||
|
||
### 例外情况
|
||
|
||
仅以下情况可以无需列出方案直接执行:
|
||
|
||
- 用户明确指定了具体技术或方案("用 XX 库"、"按 YY 方式实现")
|
||
- 纯粹的代码 bug 修复、错别字修正等无技术分歧的微调
|
||
- 用户明确要求"直接做"或"你自己定"
|
||
|
||
---
|
||
|
||
## 项目概述
|
||
|
||
**目标**:开发一个运行在 Element Call 房间中的点歌机器人(Song Request Bot)
|
||
|
||
**核心能力**:
|
||
- 监听 Matrix 房间中的点歌指令
|
||
- 在房间内返回点歌结果(歌曲信息、播放链接等)
|
||
- 支持点歌队列管理
|
||
- **必须支持 E2EE(端到端加密)房间** —— 在加密房间中也能正常工作
|
||
|
||
**技术栈基线**:
|
||
- Matrix SDK: `matrix-rust-sdk` 0.18(用户指定)
|
||
- 音乐源: yt-dlp 作为通用后端
|
||
- 运行环境:国内已有的 Matrix homeserver
|
||
|
||
---
|
||
|
||
## 当前阶段
|
||
|
||
✅ **M1-M5 已完成** —— 骨架 + 配置 + 加密 secret_store + matrix-sdk 登录/恢复 + 命令解析 + E2EE Timeline 读写 + yt-dlp backend + ffmpeg 转码 + m.audio 投递 + !req/!req-url/!queue/!np/!skip 端到端
|
||
|
||
🚧 **M6 准备开始** —— Element Call 房间兼容性验证(MSC3401 状态事件观测)
|
||
|
||
✅ v1 计划详见 `C:\Users\Administrator\.claude\plans\lexical-meandering-lighthouse.md`
|
||
|
||
### 已完成模块清单
|
||
|
||
| 模块 | 文件 | 状态 |
|
||
|---|---|---|
|
||
| CLI 骨架 | `src/main.rs` | ✅ |
|
||
| 错误类型 | `src/error.rs` | ✅ |
|
||
| TOML 配置 | `src/config.rs` | ✅ |
|
||
| 加密密钥存储 (Argon2id + AES-256-GCM) | `src/secret_store.rs` | ✅ |
|
||
| matrix-sdk Client 构造 | `src/client.rs` | ✅ |
|
||
| 登录/恢复 | `src/bootstrap.rs` | ✅ |
|
||
| 命令解析 | `src/commands.rs` | ✅ |
|
||
| Event loop + Timeline 加密通道 | `src/event_loop.rs` | ✅ |
|
||
| MusicSource trait + yt-dlp + 其他 stub | `src/music/` | ✅ |
|
||
| ffmpeg 转码 | `src/transcoder.rs` | ✅ |
|
||
| m.audio 投递 | `src/delivery/audio_upload.rs` | ✅ |
|
||
| 队列管理(内存版) | `src/queue.rs` | ✅ |
|
||
| yt-dlp 下载 | `src/downloader.rs` | ✅ |
|
||
| 每房间 worker | `src/worker.rs` | ✅ |
|
||
|
||
**测试**:24 个单元测试 + 4 个 ignored(需要 ffmpeg/yt-dlp + 网络)
|
||
|
||
### 已确认的技术决策(不可变)
|
||
|
||
1. Matrix SDK: matrix-sdk 0.18(matrix-sdk-crypto + matrix-sdk-ui)
|
||
2. 音乐源: yt-dlp 作为通用后端
|
||
3. 命令风格: 前缀 `!req` / `!queue` / `!skip`(房间中需 @-mention bot)
|
||
4. 音频编码: 立体声 Opus 128 kbit/s
|
||
5. 搜索交互: `!req-url` 直传 + 关键词搜索(reactions 选择待 M7)
|
||
6. E2EE 信任: 自动首次信任(`auto_enable_cross_signing: true`)
|
||
7. 多房间并发: 每房间独立 worker,并行
|
||
8. 依赖: rustup + stable-x86_64-pc-windows-gnu + MinGW gcc(避开 VS Build Tools)
|
||
9. secret.bin 加密: Argon2id (m=19456 KiB, t=2, p=1) + AES-256-GCM
|
||
10. 队列: v1 内存版(重启清空;后续可改 SqliteQueue 需解决 libsqlite3-sys 冲突)
|
||
11. 音频下载: yt-dlp 子进程(避免 reqwest 增加 deps)
|
||
|
||
### 待办(M6-M7)
|
||
|
||
- **M6**: Element Call 房间兼容(MSC3401 状态事件观测,确保 bot 在 call 进行中也能收发消息)
|
||
- **M7**: reactions 选择 + `!queue`/`!np`/`!skip` 完整闭环 + 队列持久化(可选) |