Files
zclaw_openfang/plans/prancy-greeting-tarjan.md
iven ce562e8bfc feat: complete Phase 1-3 architecture optimization
Phase 1 - Security:
- Add AES-GCM encryption for localStorage fallback
- Enforce WSS protocol for non-localhost WebSocket connections
- Add URL sanitization to prevent XSS in markdown links

Phase 2 - Domain Reorganization:
- Create Intelligence Domain with Valtio store and caching
- Add unified intelligence-client for Rust backend integration
- Migrate from legacy agent-memory, heartbeat, reflection modules

Phase 3 - Core Optimization:
- Add virtual scrolling for ChatArea with react-window
- Implement LRU cache with TTL for intelligence operations
- Add message virtualization utilities

Additional:
- Add OpenFang compatibility test suite
- Update E2E test fixtures
- Add audit logging infrastructure
- Update project documentation and plans

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:11:50 +08:00

445 lines
15 KiB
Markdown

# ZCLAW 项目全面架构优化方案
> 头脑风暴日期: 2026-03-21
> 目标: 全面优化 | 时间: 3个月+ | 策略: 激进架构优先
---
## 一、当前架构分析
### 1.1 现有问题总结
| 类别 | 问题 | 严重性 | 影响 |
|------|------|--------|------|
| **安全** | 浏览器 eval() XSS 风险 | 🔴 HIGH | 用户数据泄露 |
| **安全** | localStorage 凭据回退 | 🟠 MEDIUM | 密钥暴露 |
| **性能** | 流式更新重建整个数组 | 🟠 MEDIUM | 渲染卡顿 |
| **性能** | 无界消息数组 | 🟠 MEDIUM | 内存泄漏 |
| **架构** | 50+ lib 模块缺乏统一抽象 | 🟡 LOW | 维护困难 |
| **测试** | 核心模块无测试覆盖 | 🟠 MEDIUM | 回归风险 |
### 1.2 技术债务分布
```
desktop/src/
├── lib/ [50+ 模块] ← 需要模块化重组
├── store/ [15 stores] ← 需要统一模式
├── components/ [60+ 组件] ← 需要分层
└── types/ [分散] ← 需要集中管理
```
---
## 二、三种优化方案
### 方案 A: 渐进式模块化重构 (推荐)
**核心理念**: 保持现有架构,逐步提取抽象层
```
Phase 1 (4周): 安全加固 + 测试基础
├─ 修复 XSS/凭据存储问题
├─ 添加 chatStore/gateway-client 测试
└─ 建立测试覆盖率门禁
Phase 2 (4周): 性能优化
├─ 引入 Immer 优化状态更新
├─ 实现虚拟滚动 (react-window)
└─ 消息分页 + 惰性加载
Phase 3 (6周): 架构分层
├─ 提取 Core Layer (协议无关)
├─ 提取 Adapter Layer (Tauri/Web)
└─ 统一错误处理和日志
Phase 4 (4周): Intelligence 增强
├─ Rust 层功能完善
├─ TypeScript 适配器优化
└─ 记忆/心跳/反思/身份 全链路
```
**优点**:
- 风险可控,每阶段可独立验证
- 不影响现有功能交付
- 团队可并行工作
**缺点**:
- 改动分散,可能产生中间态
- 总体周期较长
---
### 方案 B: 激进架构重写
**核心理念**: 重新设计核心架构,一次性解决所有问题
```
Step 1: 定义新架构规范
├─ 分层架构: UI → Application → Domain → Infrastructure
├─ 依赖注入容器
└─ 统一事件总线
Step 2: 核心层重写
├─ 新 State Manager (基于 Immer + Middleware)
├─ 新 Client Layer (统一协议抽象)
└─ 新 Error System (分类 + 恢复)
Step 3: 迁移现有功能
├─ Store 逐个迁移
├─ 组件适配新 API
└─ 测试同步跟进
Step 4: 清理旧代码
```
**优点**:
- 一次性解决所有架构问题
- 代码质量飞跃式提升
- 未来扩展性最佳
**缺点**:
- 高风险,可能引入新 bug
- 开发周期不可控
- 需要冻结功能开发
---
### 方案 C: 领域驱动分层
**核心理念**: 按业务领域重组,每个领域独立优化
```
Domain 1: Chat (对话系统)
├─ ChatStore 重构 (Immer + 分页)
├─ 流式响应优化
└─ 虚拟滚动 + 记忆增强
Domain 2: Hands (自动化)
├─ HandStore 状态机模式
├─ 审批流程增强
└─ 执行引擎隔离
Domain 3: Intelligence (智能层)
├─ Rust 后端完善
├─ 心跳/压缩/反思/身份
└─ 缓存策略优化
Domain 4: Skills (技能系统)
├─ 技能发现/搜索优化
├─ 执行沙箱隔离
└─ 依赖管理
Cross-Cutting:
├─ 安全层 (统一加解密)
├─ 测试层 (领域测试套件)
└─ 监控层 (性能/错误追踪)
```
**优点**:
- 领域边界清晰
- 可独立演进
- 易于并行开发
**缺点**:
- 跨领域逻辑复杂
- 共享代码可能重复
- 需要重新规划目录结构
---
## 三、方案对比
| 维度 | 方案 A (渐进) | 方案 B (激进) | 方案 C (领域) |
|------|---------------|---------------|---------------|
| **风险** | 🟢 低 | 🔴 高 | 🟡 中 |
| **速度** | 🟡 中 | 🔴 慢 | 🟢 快 |
| **效果** | 🟡 中等提升 | 🟢 飞跃提升 | 🟢 显著提升 |
| **并行度** | 🟡 部分并行 | 🔴 串行 | 🟢 完全并行 |
| **推荐度** | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
---
## 四、确认方案: A + C 混合 (用户已确认)
> **关键决策**:
> - 状态管理: **VZustand** (Proxy 细粒度响应)
> - 安全策略: **Web Worker 隔离执行** (最安全)
结合渐进式和领域驱动的优点:
```
┌─────────────────────────────────────────────────────────────┐
│ Phase 1: 安全 + 测试 (2周) │
│ • 实现 Web Worker 隔离执行引擎 │
│ • 修复凭据存储问题 (加密回退) │
│ • 建立测试框架和覆盖率门禁 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Phase 2: 领域重组 (4周) │
│ • 按领域重组目录结构 │
│ • 迁移到 VZustand (Proxy 响应式) │
│ • 提取领域接口和抽象 │
│ • 统一错误处理 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Phase 3: 核心优化 (并行) (6周) │
│ Track A: Chat Track B: Hands Track C: Intelligence │
│ • VZustand 重写 • 状态机模式 • Rust 增强 │
│ • 虚拟滚动 • Web Worker • 缓存策略 │
│ • 流式优化 • 审批流增强 • 性能调优 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Phase 4: 集成 + 清理 (2周) │
│ • 跨领域集成测试 │
│ • 清理旧代码 │
│ • 文档更新 │
└─────────────────────────────────────────────────────────────┘
```
**总周期**: 约 14 周 (3.5 个月)
---
## 五、各领域详细优化点
### 5.1 智能对话系统 (Chat Domain)
| 优化项 | 当前问题 | 解决方案 | 预期收益 |
|--------|----------|----------|----------|
| 状态更新 | 每次重建数组 | **VZustand** (Proxy 细粒度) | 70% 性能提升 |
| 长对话 | 无界数组 | 分页 + 惰性加载 | 内存降低 80% |
| 虚拟滚动 | 全量渲染 | react-window | 首屏快 3x |
| 流式响应 | 回调嵌套 | AsyncGenerator | 代码简洁 |
**VZustand 架构**:
```typescript
// 基于 Proxy 的细粒度响应
const useChatStore = create(
proxy({
messages: [],
addMessage: (msg) => { messages.push(msg); } // 直接 mutate
})
);
// 组件只订阅使用的字段
function MessageList() {
const messages = useChatStore(s => s.messages); // 仅 messages 变化时重渲染
}
```
**关键改动文件**:
- `desktop/src/store/chatStore.ts` → 重写为 VZustand
- `desktop/src/components/ChatArea/MessageList.tsx`
- `desktop/src/lib/gateway-client.ts`
### 5.2 Hands 自动化 (Hands Domain)
| 优化项 | 当前问题 | 解决方案 | 预期收益 |
|--------|----------|----------|----------|
| 状态管理 | 简单状态 | 状态机模式 (XState) | 可预测性提升 |
| 审批流程 | 硬编码 | 可配置审批链 | 灵活性提升 |
| 执行隔离 | 共享上下文 | **Web Worker 隔离** | 安全性最大化 |
| 错误恢复 | 无 | 检查点 + 重试 | 可靠性提升 |
**Web Worker 隔离架构**:
```
┌─────────────────────────────────────────────────────────────┐
│ Main Thread │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ HandStore │←→│ WorkerPool │←→│ UI 更新 │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
└────────────────────────────┼────────────────────────────────┘
│ postMessage
┌─────────────────────────────────────────────────────────────┐
│ Web Worker (隔离) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Browser Executor │ │
│ │ • 无 DOM 访问 │ │
│ │ • 受限 API │ │
│ │ • 超时控制 │ │
│ │ • 错误隔离 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
**关键改动文件**:
- `desktop/src/store/handStore.ts` → 状态机模式
- `desktop/src/workers/browser-worker.ts` (新建)
- `desktop/src/lib/worker-pool.ts` (新建)
- `desktop/src-tauri/src/browser/`
### 5.3 Intelligence 层 (Intelligence Domain)
| 优化项 | 当前问题 | 解决方案 | 预期收益 |
|--------|----------|----------|----------|
| Rust 完善 | 部分功能未实现 | 补全所有命令 | 功能完整 |
| 缓存策略 | 无缓存 | LRU + TTL | 响应快 2x |
| 离线支持 | 依赖网络 | 本地优先 | 可用性提升 |
| 记忆搜索 | 简单匹配 | 向量检索 | 准确率提升 |
**关键改动文件**:
- `desktop/src-tauri/src/intelligence/*.rs`
- `desktop/src-tauri/src/memory/*.rs`
- `desktop/src/lib/intelligence-client.ts`
### 5.4 技能系统 (Skills Domain)
| 优化项 | 当前问题 | 解决方案 | 预期收益 |
|--------|----------|----------|----------|
| 搜索效率 | 遍历文件 | 索引 + 缓存 | 搜索快 10x |
| 执行沙箱 | 无隔离 | iframe/Worker | 安全性提升 |
| 依赖管理 | 手动 | 自动解析 | 易用性提升 |
**关键改动文件**:
- `desktop/src/lib/skill-loader.ts` (新建)
- `desktop/src/store/skillStore.ts`
- `skills/*/SKILL.md` 规范更新
---
## 六、安全加固专项
### 6.1 XSS 防护 - Web Worker 隔离
```typescript
// 当前问题: browser.eval() 直接在主线程执行用户输入
// 解决方案: Web Worker 完全隔离执行
// 主线程: worker-pool.ts
class BrowserWorkerPool {
private workers: Worker[] = [];
async execute(script: string, args: unknown[]): Promise<unknown> {
const worker = this.getAvailableWorker();
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
worker.terminate();
reject(new Error('Execution timeout'));
}, 30000);
worker.onmessage = (e) => {
clearTimeout(timeout);
if (e.data.error) reject(new Error(e.data.error));
else resolve(e.data.result);
};
worker.postMessage({ type: 'eval', script, args });
});
}
}
// Worker: browser-worker.ts
self.onmessage = async (e) => {
const { type, script, args } = e.data;
try {
// 无 DOM 访问,受限 API
const result = await executeScript(script, args);
self.postMessage({ result });
} catch (error) {
self.postMessage({ error: error.message });
}
};
```
### 6.2 凭据存储
```typescript
// 当前问题: localStorage 明文回退
// 解决方案: 加密回退 + 密钥派生
const ENCRYPTION_KEY = await deriveKey(userPassword, salt);
const encrypted = await encrypt(privateKey, ENCRYPTION_KEY);
localStorage.setItem(KEY, encrypted);
```
### 6.3 WebSocket 安全
```typescript
// 当前问题: 非 localhost 允许 ws://
// 解决方案: 强制 wss:// + 证书验证
if (!url.startsWith('wss://') && !isLocalhost(url)) {
throw new SecurityError('Non-localhost must use WSS');
}
```
---
## 七、测试策略
### 7.1 测试金字塔
```
/\
/ \ E2E Tests (Playwright)
/────\ - 关键用户流程
/ \ - 10-15 个核心场景
/────────\
/ \ Integration Tests (Vitest)
/────────────\ - Store + Client 集成
/ \- API 契约测试
/────────────────\
/ \ Unit Tests (Vitest)
──────────────────── - 纯函数/工具
- 80%+ 覆盖率目标
```
### 7.2 覆盖率目标
| 模块 | 当前 | 目标 |
|------|------|------|
| `chatStore.ts` | 0% | 90% |
| `gateway-client.ts` | 0% | 85% |
| `handStore.ts` | 0% | 85% |
| `intelligence-client.ts` | 0% | 80% |
| 工具函数 | ~40% | 95% |
---
## 八、验证计划
### 8.1 功能验证
- [ ] 聊天流式响应正常
- [ ] Hands 触发和审批正常
- [ ] Intelligence 层功能完整
- [ ] 技能搜索和执行正常
- [ ] 配置读写正常
### 8.2 性能验证
- [ ] 首屏加载 < 2s
- [ ] 消息渲染 60fps
- [ ] 1000+ 消息流畅滚动
- [ ] 内存占用 < 500MB
### 8.3 安全验证
- [ ] XSS 攻击防护有效
- [ ] 凭据存储安全
- [ ] WebSocket 加密传输
---
## 九、风险与缓解
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|----------|
| 引入新 bug | | | 每阶段充分测试 |
| 进度延期 | | | 预留 buffer |
| 架构决策失误 | | | 原型验证 |
| 团队不熟悉新架构 | | | 培训 + 文档 |
---
## 十、下一步行动
1. **确认方案**: 用户选择最终方案
2. **创建详细计划**: 使用 writing-plans skill
3. **开始执行**: Phase 1 安全加固