feat: M2.1 客户端骨架、BLE 修复、仓库整理与现状板

- BLE: 修复 BlueZ LocalName 与 Includes 冲突,串行注册与退避
- HTTP: 语音对话补 Live2D talking 标志与 session;Web 补 X-Session-Id
- Flutter: 角色/对话/模型页 + API,Gradle/依赖升级,麦克风权限
- 文档: 新增 docs/STATUS.md,校准 CLAUDE/PROGRESS/README
- 清理: 移除根目录截图与临时模型,运维脚本迁入 scripts/device
This commit is contained in:
2026-07-09 12:41:34 +08:00
parent 7cb8cee70d
commit 6f7e24db63
51 changed files with 2674 additions and 351 deletions

204
docs/PLAN_M2.1_NEXT.md Normal file
View File

@@ -0,0 +1,204 @@
# M2.1 下一阶段实施计划
> 创建2026-07-09
> 背景功能不完善AI 与 Live2D/视频**尚未完整联动**App/Web 为半成品。
> 对照:`docs/STATUS.md`(现状)· `docs/M2.1_PRD.md`(产品定义)
---
## 0. 目标(本阶段完成的定义)
**可演示的闭环P0 验收)**
1. 设备开机 → App/Web 可连
2. 切换角色(至少狗/猫/Live2D 配置)→ 画面与人设同步
3. 文字对话 → 客户端播 TTS → **画面有“在说话”反馈**
4. App 按住说话 → 同上
5. 模型列表可见;切换 LLM 后下一回合生效(失败有明确提示)
**不做本阶段(明确边界)**
- 设备本机麦克风/扬声器直连(硬件未接)
- 精细口型同步 / 流式打断
- 数字人/歌姬全套新视频素材制作
- 云端 LLM 实装
---
## 1. 现状结论(计划前提)
| 层 | 现状 |
|----|------|
| AI 管线 | 本地 ASR/LLM/TTS 可跑HTTP `/api/chat/*` 可用 |
| Live2D | 有字幕 `Subtitle``live2d_talking` 标志在 HTTP 内,**未驱动嘴部动画** |
| 视频状态机 | 有 `talk_state` 配置字段;**对话不会 ChangeScene** |
| App | 角色/对话/模型页已写;真机旅程未系统验 |
| Web | chat 控制台有入口HTTP 录音受限 |
| 仓库 | 2026-07-09 已提交整理与骨架改动(见 git log |
---
## 2. 工作包拆分
### WP-A · AI ↔ 画面联动(核心缺口)
**A1. Live2D 说话态接通(优先)**
| 步骤 | 内容 | 验收 |
|------|------|------|
| A1.1 | 定义共享通道:消息 `Message::Live2dTalking { on: bool }` **或** 注入 Arc 状态到 Live2D 插件 | 二选一,文档写清 |
| A1.2 | HTTP chat 成功路径:开始 `talking=true`,结束按**音频时长或字数**回 `false` | 与 TTS 结束大致对齐(误差 ≤1.5s 可接受) |
| A1.3 | Live2D 渲染循环读 talking → `animation.set_talking` | 说话时嘴部开合,结束后回 idle |
| A1.4 | 字幕路径保持:`Subtitle` 继续走 | 字+嘴同时有反馈 |
**A2. 视频角色 talk 状态(次优先)**
| 步骤 | 内容 | 验收 |
|------|------|------|
| A2.1 | chat 开始:向 video 发 `ChangeScene(config.character.talk_state)` 或等价 trigger | 有 talk 片段则切过去 |
| A2.2 | chat 结束:回 `idle`(或配置的默认态) | 不卡在 talk |
| A2.3 | 无 talk 状态时优雅降级(日志 + 保持当前态,不 500 | 猫狗旧包不炸 |
**A3. 时长与互斥**
| 步骤 | 内容 |
|------|------|
| A3.1 | 优先用回复音频时长驱动 talking 窗口;无音频则字数估算 |
| A3.2 | 对话进行中拒绝二次对话 / 切角色(或排队策略写死一种) |
**负责建议**:内核/HTTP张明远 or 王浩然)+ Live2D/视频(李思琪)
**预估**A1 12 天 · A2 1 天 · A3 0.5 天
---
### WP-B · 设备对齐与回归
| 步骤 | 内容 | 验收 |
|------|------|------|
| B1 | 本机已提交代码同步到设备 `192.168.31.105` | git 一致或 rsync 可追溯 |
| B2 | `cargo check --workspace --all-targets` 零 warning | 贴输出 |
| B3 | `cargo test --workspace` 全绿 | 贴输出 |
| B4 | `systemctl --user restart showen_v2` + BLE ActiveInstances=1 | 服务稳定 |
| B5 | `POST /api/chat/text` 冒烟 | 有 reply_textLive2D 有嘴/字幕 |
---
### WP-C · App 真机验收与修补
| 步骤 | 内容 | 验收 |
|------|------|------|
| C1 | 安装 debug APK配置 `192.168.31.105:5000` | 能连 |
| C2 | 角色页切换 3 套配置 | 画面+人设变 |
| C3 | 文字对话 + 自动播 TTS + 重播 | 有声有字 |
| C4 | 按住说话一轮 | 转写+回复(允许慢) |
| C5 | 模型页列表/切换 | 失败有文案 |
| C6 | 按失败项修 Flutter超时、503、权限 | 不再静默失败 |
**依赖**WP-A 至少完成 A1 后再验“说话联动”。
---
### WP-D · Web 验收与修补
| 步骤 | 内容 |
|------|------|
| D1 | 角色/文字对话/模型三页真机点通 |
| D2 | HTTP 下录音禁用时的固定文案(与 PRD 一致) |
| D3 | 切角色清空会话上下文 |
---
### WP-E · 产品化收尾P1AD 之后)
| 步骤 | 内容 |
|------|------|
| E1 | App 对话历史本地持久化 + 一键清空 |
| E2 | 模型下载进度轮询/失败重试 UX |
| E3 | release APK 签名与安装说明 |
| E4 | M1.2 tag `m1.2`(老板) |
| E5 | 素材:数字人/歌姬 talk/idle外部依赖可并行 |
---
## 3. 推荐执行顺序
```text
Day 0 本计划评审(老板/CEO
Day 1 WP-A1 Live2D talking 接通 + B 设备同步回归
Day 2 WP-A2 视频 talk 降级策略 + A3 互斥
Day 3 WP-C App 真机四旅程 + 修洞
Day 4 WP-D Web 点通 + 文档 STATUS 更新
Day 5+ WP-E 按优先级穿插
```
---
## 4. 技术要点备忘(实现时)
### 4.1 Live2D talking 推荐实现
```
HTTP chat 开始
→ state.set_live2d_talking(true)
→ tx.send(Message::Live2dTalking { on: true }) // 或等价
→ tx.send(Message::Subtitle { text })
Live2DPlugin::handle_message
→ renderer.set_talking(on)
HTTP chat 结束spawn 延迟)
→ set_live2d_talking(false) + Live2dTalking { on: false }
```
避免 Live2D 去轮询 HTTP 内部 AtomicBool跨插件耦合差
### 4.2 视频 talk
```
render_type == video 时:
chat 开始 → PlayerCommand::ChangeScene(talk_state)
chat 结束 → ChangeScene("idle") // 或配置 default_idle
无该 scene 时: 忽略并 log不返回 5xx
```
### 4.3 验证命令(设备)
```bash
ssh -p 2222 showen@192.168.31.105
systemctl --user status showen_v2
curl -sS -m 60 -X POST http://127.0.0.1:5000/api/chat/text \
-H 'Content-Type: application/json' \
-d '{"text":"你好","session_id":"plan_test"}'
# 同时观察 Live2D 嘴部与字幕
```
---
## 5. 风险
| 风险 | 应对 |
|------|------|
| 对话延迟 515s 体感差 | 先保证正确联动;优化单独立项(锁核/更小模型) |
| 宠物包无 talk 片段 | 强制降级,不阻塞 Live2D 路径 |
| 设备与 git 漂移 | B1 强制对齐后再验 |
| 录音权限/机型差异 | App 明确权限引导;失败可走文字 |
---
## 6. 完成检查清单(勾选)
- [ ] Live2D对话时嘴部动画 + 字幕
- [ ] 视频:有 talk 则切 talk无则降级
- [ ] App角色 / 文字 / 语音 / 模型 四旅程通过
- [ ] Web角色 / 文字对话 / 模型通过
- [ ] 设备 `cargo test --workspace` 全绿
- [ ] `docs/STATUS.md` 矩阵更新为与实机一致
- [ ] 可选release APK
---
## 7. 变更记录
| 日期 | 说明 |
|------|------|
| 2026-07-09 | 初稿:联动缺口 + 分 WP 计划;对应 git 提交含骨架与整理 |

170
docs/STATUS.md Normal file
View File

@@ -0,0 +1,170 @@
# ShowenV2 项目现状板
> **更新2026-07-09**
> 用途:一页看清「能干什么 / 不能干什么 / 下一步做什么」。
> 操作派发仍以 `CLAUDE.md` 为 CEO 手册;本文件是**功能成熟度**权威清单。
---
## 1. 里程碑总览
| 里程碑 | 状态 | 说明 |
|--------|------|------|
| **M1.1** | ✅ 完成 | 插件微内核、视频/设备/HTTP/BLE/WiFi 骨架 |
| **M1.2** | ✅ 验收通过 | 目标机 147/147 测试全绿;仅差老板打 tag `m1.2` |
| **M2.1** | 🟡 **进行中(半成品)** | 语音数字生命 V1后端/网页/App 已有骨架,**体验与验收未闭环** |
---
## 2. 仓库结构(整理后)
```
ShowenV2/
├── CLAUDE.md # CEO 操作手册(派发/铁律/当前状态)
├── README.md # 架构与快速开始
├── PROGRESS.md # 里程碑摘要
├── docs/
│ ├── STATUS.md # ← 本文件(功能成熟度)
│ ├── M2.1_PRD.md # M2.1 产品需求
│ └── ...
├── src/
│ ├── core/ # 微内核
│ └── plugins/ # video / http / ble / wifi / device / screen / live2d / ai
├── configs/ # 角色内容包 JSONdog/cat/live2d_anime
├── clients/flutter/ # 安卓控制 App
├── scripts/device/ # 设备运维脚本(从根目录迁入)
├── tests/ # M1.2 集成测试
└── souls/ # 团队档案
```
**根目录禁止再堆**:截图 `*.xwd`、临时模型 `.haru.*`、一次性 `.*.sh`
---
## 3. 能力成熟度矩阵
图例:✅ 可用 · 🟡 半成品 · ❌ 缺失 · 🚫 本期不做
### 3.1 设备端Linux ARM64 · 192.168.31.105
| 能力 | 状态 | 备注 |
|------|------|------|
| 开机自启 `showen_v2.service` | ✅ | `Restart=always`,用户级 + Linger |
| 视频状态机 / Live2D 渲染 | ✅ | 设备画面主路径 |
| HTTP :5000 Web + API | ✅ | |
| BLE 广播 + GATT 配网 | ✅ | 已修 LocalName/Includes 冲突;广播实例=1 |
| WiFi (nmcli) | ✅ | |
| AI 对话管线 ASR→LLM→TTS | 🟡 | 设备实测文字对话可通;延迟数秒~十余秒 |
| 模型管理 API | 🟡 | 列表/下载/切换/删除有;进度/配额 UX 待验 |
| 角色配置切换 API | ✅ | `/api/config/available` + `switch` 带 character 元信息 |
| 单实例锁 | ❌ | 防御性双保险未做 |
| 设备本机麦克风/扬声器对话 | 🚫 | 硬件未接V1 声音走客户端 |
### 3.2 网页控制端(`chat.html` + `chat.js`
| 能力 | 状态 | 备注 |
|------|------|------|
| 播放/触发/配置/视频/文件/WiFi | ✅ | M1 存量 |
| 角色切换 UI | 🟡 | 有入口,端到端验收不足 |
| 文字对话 + 浏览器播 TTS | 🟡 | API 通;人设/状态联动待系统验 |
| 按住说话 | 🟡 | HTTP 下 getUserMedia 受限PRD 允许降级 |
| 模型管理 UI | 🟡 | 有入口,下载进度/错误态未系统验 |
| 与 App 状态互相同步 | 🟡 | 依赖 WS/轮询,未做验收用例 |
### 3.3 安卓 AppFlutter · v0.4 debug APK
| 能力 | 状态 | 备注 |
|------|------|------|
| 设备连接 / 播放 / 网络 / BLE 配网 / 设置 | ✅ | M1 能力 |
| 角色页 | 🟡 | 代码已加,**真机体验未验** |
| 对话页(文字+按住说话+播回复) | 🟡 | 代码已加,**真机体验未验** |
| 模型管理页 | 🟡 | 代码已加,**真机体验未验** |
| debug APK | ✅ | `clients/flutter/build/app/outputs/flutter-apk/app-debug.apk` (~146MB) |
| release 签名包 | ❌ | 未打 |
| 对话历史本地持久化 / 隐私文案 | ❌ | PRD 有要求 |
| 角色卡片封面图 | ❌ | API 未提供 cover |
### 3.4 内容与素材
| 项 | 状态 |
|----|------|
| dog / cat 视频包 | ✅ 可用(路径仍偏仓库外历史形态) |
| live2d_anime 包 | 🟡 有配置,素材依赖设备本地 `configs/live2d/` |
| 数字人/歌姬完整 4 状态视频包 | ❌ 素材未齐PRD 最大外部依赖) |
| 角色 `talk` 状态全覆盖 | 🟡 宠物包可降级 |
---
## 4. 未提交改动本机工作区2026-07-09
以下在仓库 **working tree**,尚未 commit按老板规则不代提交
| 区域 | 内容 |
|------|------|
| `src/plugins/ble/` | BLE 广播 LocalName 修复 + 串行注册 |
| `src/plugins/http/` | chat/audio 说话态/sessionchat.js session 头 |
| `clients/flutter/` | M2.1 三角色/对话/模型页 + Gradle/依赖升级 |
| 根目录清理 | 移除 xwd/haru 垃圾;脚本迁 `scripts/device/` |
设备端:上述 BLE/HTTP 二进制可能已部署,但 **git 与设备代码可能不完全一致**,合并前需同步。
---
## 5. 不完善点(按优先级)
### P0 — 不做则无法说「M2.1 可用」
1. **真机验收闭环**App 装机 → 角色切换 → 文字/语音对话 → 模型列表/切换
2. **设备 ↔ 本机代码对齐**commit + 设备 `git pull`/同步 + `cargo test`
3. **对话失败可理解**AI 未就绪 / 超时 / 模型缺失时App/Web 明确提示
### P1 — 体验完整度
4. App 对话历史本地存储 + 清空
5. 切换角色时清空会话上下文App 已调 clearWeb 需确认)
6. 模型下载进度实时刷新与失败重试
7. Web HTTP 录音限制的产品文案统一
8. release APK 与安装渠道
### P2 — 技术债 / 收尾
9. M1.2 tag `m1.2`
10. 单实例保护
11. `sanitize_filename` 测试转正
12. CursorVisibility 等 Phase2 消息清理
13. 数字人/歌姬素材管线
---
## 6. 建议下一轮工作顺序
```text
1) 老板/本机:提交当前工作区改动(或拆成 ble / http / flutter 三提交)
2) 设备同步 + cargo test --workspace
3) App 真机:配网 → 角色 → 对话 → 模型 四条用户旅程
4) 按失败项修 P0
5) 再谈素材与 release
```
---
## 7. 环境速查
| 环境 | 要点 |
|------|------|
| 设备 SSH | `ssh -p 2222 showen@192.168.31.105`(密码 showen |
| 设备 Web | `http://192.168.31.105:5000/` |
| 本机 Flutter | `source ~/.showen_dev_env` · Flutter 3.44.5 · JDK17 · Android SDK36 |
| 本机 APK | `clients/flutter/build/app/outputs/flutter-apk/app-debug.apk` |
---
## 8. 文档导航
| 需求 | 文件 |
|------|------|
| 派任务 / 铁律 | `CLAUDE.md` |
| 功能成熟度(本页) | `docs/STATUS.md` |
| M2.1 产品定义 | `docs/M2.1_PRD.md` |
| 里程碑摘要 | `PROGRESS.md` |
| 架构入门 | `README.md` |