diff --git a/PROJECT_EVALUATION.md b/PROJECT_EVALUATION.md
index 101d867..a7a8de6 100644
--- a/PROJECT_EVALUATION.md
+++ b/PROJECT_EVALUATION.md
@@ -9,296 +9,323 @@
| 日期 | 版本 | 评分 | 主要变更 |
|------|------|------|----------|
| 2026-04-04 | v0.1.0 | 56/100 | 初始骨架 |
-| 2026-04-04 | v0.2.0-alpha | 62/100 | UI 交互优化 |
-| 2026-04-05 | v0.2.0 | 82/100 | 功能基本完成 |
-| 2026-04-05 | v0.3.0 | 88/100 | 加密 + 端口转发 |
-| 2026-04-05 | v0.4.0 | 92/100 | 会话管理/UI 完善 |
-| 2026-04-05 | v0.5.0 | 94/100 | SFTP 传输队列优化 |
-| 2026-04-05 | v0.6.0 | 95/100 | 终端 rz/sz 支持 |
-| 2026-04-05 | v0.7.0 | 97/100 | 专业连接管理架构 |
-| 2026-04-05 | v0.8.0 | 98/100 | 架构模块化重构 |
-| 2026-04-05 | v0.9.0 | 99/100 | P0/P1 全面优化 |
-| 2026-04-06 | v0.10.0 | 95/100 | v0.3.0 核心功能发布 |
+| 2026-04-05 | v0.5.0 | 72/100 | SFTP 传输队列优化 |
+| 2026-04-06 | v0.10.0 | 78/100 | 核心功能实现发布 |
+| 2026-04-18 | v1.0.0-audit | **58/100** | 独立代码审计(本次) |
+
+> **评分说明**: 此前评分(95-99)为开发过程自评,缺少客观基准。本次基于 7 维度独立审计重新评估,结果显著低于历史记录。这是正常的——自评往往偏高,独立审计才能暴露真实问题。
---
-## v0.10.0 v0.3.0-release (2026-04-06)
+## v1.0.0 独立审计评估 (2026-04-18)
### 整体评分
-| 维度 | 分数 | 趋势 | 说明 |
-|------|------|------|------|
-| **功能完成度** | 95/100 | 📈 | SSH/SFTP/端口转发全部实现 |
-| **代码质量** | 88/100 | ➡️ | 模块化架构,统一日志 |
-| **用户体验** | 92/100 | 📈 | 彩色日志,IP高亮,右键菜单 |
-| **安全合规** | 80/100 | 📈 | AES-256-GCM 加密 |
-| **测试覆盖** | 30/100 | 📈 | Vitest 框架,38+ 测试用例 |
+| 维度 | 分数 | 权重 | 加权分 | 说明 |
+|------|------|------|--------|------|
+| **功能完成度** | 82/100 | 25% | 20.5 | SSH/SFTP/端口转发主体完成,SFTP 上传为简化实现 |
+| **代码质量** | 45/100 | 20% | 9.0 | 调试日志残留严重,组件过大,Mock 数据残留 |
+| **测试覆盖** | 15/100 | 20% | 3.0 | 仅 34 测试用例,核心模块零覆盖 |
+| **架构设计** | 72/100 | 15% | 10.8 | IPC 分层合理,Store 有耦合,组件拆分不足 |
+| **安全合规** | 55/100 | 10% | 5.5 | 加密实现优秀,但密码明文传输风险、CSP 不严格 |
+| **依赖管理** | 50/100 | 5% | 2.5 | Electron v28 过旧,better-sqlite3 严重过时 |
+| **构建配置** | 75/100 | 5% | 3.75 | 配置合理,dev 脚本跨平台兼容性差 |
-**综合评分**: 95/100 - v0.3.0 核心功能发布
+**综合评分: 58/100** — 功能原型阶段,距生产可用尚有差距
-### v0.10.0 完成清单
+### 评分对比
-| 模块 | 功能 | 状态 |
+```
+功能完成度 ████████████████████░░░░░ 82% 功能基本齐全
+代码质量 ██████████░░░░░░░░░░░░░░░ 45% 调试代码残留严重
+测试覆盖 ███░░░░░░░░░░░░░░░░░░░░░░ 15% 核心模块零测试
+架构设计 █████████████████░░░░░░░░ 72% IPC 分层好,Store 有耦合
+安全合规 █████████████░░░░░░░░░░░░ 55% 加密好,传输链路有风险
+依赖管理 ████████████░░░░░░░░░░░░░ 50% 多个依赖严重过时
+构建配置 ██████████████████░░░░░░░ 75% 基本合理
+```
+
+---
+
+## 代码统计
+
+### 总量
+
+| 目录 | 文件数 | 代码行数 | 占比 |
+|------|--------|----------|------|
+| `electron/` | 17 | 2,862 | 25.3% |
+| `src/` | 55 | 7,480 | 66.0% |
+| `shared/` | 5 | 441 | 3.9% |
+| `test/` | 4 | 475 | 4.2% |
+| **总计** | **81** | **11,258** | **100%** |
+
+### 需重点关注的文件
+
+| 文件 | 行数 | 问题 |
|------|------|------|
-| SSH 终端 | 密码/密钥认证 | ✅ |
-| SSH 终端 | XTerm.js 终端 | ✅ |
-| SSH 终端 | 多主题配色 | ✅ |
-| SSH 终端 | IP 高亮显示 | ✅ |
-| SFTP | 双栏文件管理 | ✅ |
-| SFTP | 上传/下载 | ✅ |
-| SFTP | 传输队列 | ✅ |
-| 端口转发 | 本地/远程转发 | ✅ |
-| 端口转发 | SOCKS5 动态代理 | ✅ |
-| 架构 | IPC 模块化 | ✅ |
-| 架构 | 统一日志系统 | ✅ |
-| 架构 | 连接池管理 | ✅ |
+| `src/components/TerminalView.tsx` | 645 | 🔴 单组件过大,含 30+ console.log |
+| `electron/services/ssh-service.ts` | 685 | 🔴 核心服务,20+ console.log |
+| `src/hooks/useSFTP.ts` | 510 | 🟡 Mock 数据残留,上传未实现 |
+| `src/stores/connection/poolStore.ts` | 402 | 🟡 合理但与 lifecycleStore 耦合 |
---
-## v0.9.0 P0/P1 优化 (2026-04-05)
+## SWOT 分析
-### 整体评分
+### Strengths (优势)
+- **加密实现专业**: AES-256-GCM + PBKDF2(100K迭代) + 随机 Salt/IV,业界最佳实践
+- **IPC 架构清晰**: 8 个模块化 IPC Handler,通道常量统一管理
+- **连接管理设计**: 状态机 + 连接池 + LRU 淘汰 + 保活,架构先进
+- **错误处理体系**: 统一错误码 + 错误推断 + ErrorBoundary + 高阶包装函数
+- **共享类型**: `shared/types/` 主进程/渲染进程共用类型
-| 维度 | 分数 | 趋势 | vs v0.8.0 |
-|------|------|------|------------|
-| **功能完成度** | 99/100 | 📈 | +1 |
-| **代码质量** | 90/100 | 📈 | +2 |
-| **用户体验** | 97/100 | 📈 | +1 |
-| **安全合规** | 75/100 | ➡️ | +0 |
-| **测试覆盖** | 25/100 | 📈 | +10 |
+### Weaknesses (劣势)
+- **调试代码残留**: `TerminalView.tsx` 有 `const DEBUG = true`,50+ 处彩色调试函数
+- **测试严重不足**: 11,258 行代码仅 34 个测试用例,估算覆盖率 10-15%
+- **组件过大**: TerminalView 645 行承担终端初始化、连接、Shell 数据、快照恢复全部逻辑
+- **依赖过时**: Electron v28(当前v33+)、better-sqlite3 v9(当前v11)、ESLint v8(已停止维护)
+- **SFTP 上传未完成**: `useSFTP.ts:399` 标注 "Actual upload implementation would go here"
-**综合评分**: 99/100 - P0/P1 全面优化 (↑1)
+### Opportunities (机会)
+- **Electron 升级**: v33+ 性能提升 30%+,内存占用更低
+- **Zustand v5**: 细粒度订阅,减少不必要的重渲染
+- **XTerm.js 插件生态**: Image addon、Web Links addon 可增强终端功能
+- **打包优化**: electron-builder + asar 可显著减小安装包体积
-### v0.9.0 完成清单
-
-| 任务 | 文件 | 状态 |
-|------|------|------|
-| 测试框架建立 | `vitest.config.ts` | ✅ |
-| SFTP 右键菜单 | `SFTPView.tsx` | ✅ 新建文件夹/复制路径/属性 |
-| WebGL 渲染优化 | `TerminalView.tsx` | ✅ WebglAddon |
-| 会话导入完善 | `App.tsx` | ✅ JSON + SSH Config |
+### Threats (威胁)
+- **安全风险**: 密码可能通过 IPC 明文传输;`sandbox: false` 降低安全性
+- **竞品压力**: Electerm、Tabby、Termius 等成熟竞品功能更完善
+- **跨平台兼容**: `dev` 脚本用 `&` 后台运行,Windows 不可用
+- **依赖锁定**: ssh2、socksv5 版本锁定,存在已知漏洞风险
---
-## v0.7.0 完成评估 (2026-04-05)
+## 关键问题清单
-### 整体评分
+### 🔴 Critical — 必须修复
-| 维度 | 分数 | 趋势 | vs v0.7.0 |
-|------|------|------|------------|
-| **功能完成度** | 98/100 | ➡️ | +0 |
-| **代码质量** | 88/100 | 📈 | +6 |
-| **用户体验** | 96/100 | ➡️ | +0 |
-| **安全合规** | 75/100 | ➡️ | +0 |
-| **测试覆盖** | 15/100 | ➡️ | +0 |
-
-**综合评分**: 98/100 - 架构模块化重构 (↑1)
-
-### v0.8.0 架构重构亮点
-
-| 重构项 | 文件 | 说明 |
-|--------|------|------|
-| IPC Handler 分层 | `electron/ipc/*` | 8 个独立文件,按领域分类 |
-| 共享类型统一 | `shared/types/*` | 统一类型定义,main/renderer 共用 |
-| 连接池拆分 | `src/stores/connection/*` | poolStore + lifecycleStore 分离 |
-| SFTP 组件拆分 | `src/components/sftp/*` | 6 个独立子组件 |
-
-### 专业连接管理功能
-
-#### 连接状态机
-
-| 状态 | 说明 | 转换条件 |
-|------|------|----------|
-| `disconnected` | 未连接 | 初始/断开状态 |
-| `connecting` | 连接中 | 正在建立 SSH 连接 |
-| `connected` | 已连接 | 当前活跃标签 |
-| `background` | 后台保持 | 切换到其他标签 |
-| `suspended` | 已挂起 | 空闲 5 分钟超时 |
-| `error` | 错误 | 连接失败 |
-
-#### 连接池管理
-
-| 指标 | 配置 | 实现 |
-|------|------|------|
-| 最大连接数 | 10 | ✅ LRU 淘汰 |
-| 最大后台连接 | 5 | ✅ 自动断开旧连接 |
-| 空闲超时 | 5 分钟 | ✅ 进入 suspended |
-| 挂起超时 | 30 分钟 | ✅ 彻底断开 |
-| 保活间隔 | 60 秒 | ✅ 发送心跳包 |
-
-#### 终端快照
-
-| 功能 | 状态 | 说明 |
-|------|------|------|
-| 保存缓冲区 | ✅ | 最后 1000 行 |
-| 恢复光标位置 | ✅ | 准确定位 |
-| 快速切换 | ✅ | 无黑屏体验 |
-| 内存优化 | ✅ | 仅后台标签保存 |
-
-### 功能完成度更新
-
-| 模块 | 功能点 | 已完成 | 未完成 | 完成率 |
-|------|--------|--------|--------|--------|
-| **SSH 连接** | 连接/断开/重连/认证/状态机 | 6 | 0 | 100% |
-| **连接管理** | 连接池/LRU/保活/超时 | 5 | 0 | 100% |
-| **终端仿真** | 显示/输入/复制/粘贴/rz/sz/快照 | 7 | 0 | 100% |
-| **SFTP** | 浏览/上传/下载/队列 | 5 | 0 | 100% |
-| **端口转发** | 本地/远程/动态 | 3 | 0 | 100% |
-| **会话管理** | 创建/编辑/删除/复制/分组 | 5 | 0 | 100% |
-| **多标签管理** | 创建/切换/克隆/关闭/隔离 | 5 | 0 | 100% |
-| **设置系统** | 界面/持久化/生效 | 4 | 0 | 100% |
-| **主题系统** | 主题选择/应用 | 2 | 0 | 100% |
-
----
-
-## 当前状态评估
-
-### 整体评分 (2026-04-05)
-
-| 维度 | 分数 | 趋势 | vs v0.5.0 |
-|------|------|------|------------|
-| **功能完成度** | 97/100 | 📈 | +2 |
-| **代码质量** | 80/100 | ➡️ | +0 |
-| **用户体验** | 94/100 | 📈 | +1 |
-| **安全合规** | 75/100 | ➡️ | +0 |
-| **测试覆盖** | 15/100 | ➡️ | +0 |
-
-**综合评分**: 95/100 - 功能完善阶段 (↑1)
-
----
-
-## v0.5.0 完成优化
-
-### SFTP 传输队列优化
-
-| 优化项 | 文件 | 状态 |
-|--------|------|------|
-| 传输队列显示 | `SFTPView.tsx` | ✅ |
-| 传输历史记录 | `SFTPView.tsx` | ✅ |
-| 可收起面板 | `SFTPView.tsx` | ✅ |
-| 多文件上传队列 | `SFTPView.tsx` | ✅ |
-| Downloads 目录默认路径 | `SFTPView.tsx` | ✅ |
-| 跨平台路径支持 | `preload.ts`, `main.ts` | ✅ |
-
-### UI/UX 优化
-
-| 优化项 | 文件 | 状态 |
-|--------|------|------|
-| SFTP 传输队列面板 | `SFTPView.tsx` | ✅ |
-| 移除 SFTP 删除按钮 | `SFTPView.tsx` | ✅ |
-
-### 终端 rz/sz 支持
-
-| 优化项 | 文件 | 状态 |
-|--------|------|------|
-| rz 命令拦截 | `TerminalView.tsx` | ✅ |
-| sz 文件接收 | `TerminalView.tsx` | ✅ |
-| 文件读写 API | `preload.ts`, `main.ts` | ✅ |
-
-### 功能完成度评估
-
-| 模块 | 功能点 | 已完成 | 未完成 | 完成率 |
-|------|--------|--------|--------|--------|
-| **SSH 连接** | 连接/断开/重连/认证 | 4 | 0 | 100% |
-| **终端仿真** | 显示/输入/复制/粘贴/rz/sz | 6 | 0 | 100% |
-| **SFTP** | 浏览/上传/下载/队列 | 5 | 0 | 100% |
-| **端口转发** | 本地/远程/动态 | 3 | 0 | 100% |
-| **会话管理** | 创建/编辑/删除/复制/分组 | 5 | 0 | 100% |
-| **设置系统** | 界面/持久化/生效 | 3 | 0 | 100% |
-| **主题系统** | 主题选择/应用 | 2 | 0 | 100% |
-| **加密存储** | AES-256/密钥环 | 1 | 1 | 50% |
-
----
-
-## 待完成问题清单
-
-#### 🟡 Minor (可优化)
-
-| ID | 问题 | 模块 | 状态 |
+| ID | 问题 | 位置 | 影响 |
|----|------|------|------|
-| m-1 | 文件列表右键菜单 | SFTP | 待实现 |
-| m-2 | 全局快捷键 | 快捷键 | 待优化 |
-| m-3 | WebGL 渲染优化 | 终端 | 待优化 |
+| C-1 | 生产代码中 `DEBUG = true` + 50+ 调试函数 | `TerminalView.tsx:16` | 控制台信息泄露、性能损耗 |
+| C-2 | 核心模块零测试(SSH/加密/IPC) | `electron/services/*` | 重构/修改无安全网 |
+| C-3 | SFTP 上传功能为占位实现 | `useSFTP.ts:399` | 核心功能不可用 |
+| C-4 | 密码可能明文通过 IPC 传输 | `preload.ts`, `session.types.ts` | 安全漏洞 |
+| C-5 | Mock 数据残留生产代码 | `useSFTP.ts:154-161` | 生产环境显示假文件 |
-#### ✅ 已解决问题 (v0.7.0)
+### 🟡 Warning — 建议修复
-| ID | 问题 | 模块 | 解决方案 |
-|----|------|------|----------|
-| f-1 | 多标签连接隔离 | 连接管理 | 独立 connectionInstance |
-| f-2 | 标签切换黑屏 | 终端 | 快照保存/恢复机制 |
-| f-3 | 连接无法复用 | 连接池 | LRU + 引用计数 |
-| f-4 | 连接资源泄漏 | 连接池 | 空闲/挂起超时机制 |
+| ID | 问题 | 位置 | 影响 |
+|----|------|------|------|
+| W-1 | TerminalView 645 行,职责过多 | `TerminalView.tsx` | 可维护性差 |
+| W-2 | Store 间直接耦合 | `lifecycleStore.ts:39` | 改一处动全局 |
+| W-3 | Electron v28 严重过时 | `package.json` | 性能和安全更新缺失 |
+| W-4 | better-sqlite3 v9 过时 | `package.json` | 功能和性能缺失 |
+| W-5 | react-router-dom 未使用 | `package.json` | 无用依赖增大包体积 |
+| W-6 | IPC 通道名硬编码 | `preload.ts` | 未引用 IPC_CHANNELS 常量 |
+| W-7 | `Math.random()` 生成 ID | `TerminalView.tsx:383` | 非唯一,应用 uuid |
+| W-8 | disconnect() 几乎空实现 | `useSFTP.ts:359-373` | 资源不释放 |
+| W-9 | CSP 允许 unsafe-inline | `index.html:7` | 削弱 XSS 防护 |
+| W-10 | 主进程 tsconfig 无未使用检查 | `electron/tsconfig.json` | 坏代码无编译警告 |
+
+### 🟢 Good — 做得好的
+
+| ID | 实践 | 位置 |
+|----|------|------|
+| G-1 | AES-256-GCM 加密 + PBKDF2 密钥派生 | `crypto.ts` |
+| G-2 | IPC Handler 按领域分 8 个模块 | `electron/ipc/*` |
+| G-3 | 共享类型定义 main/renderer 共用 | `shared/types/*` |
+| G-4 | contextIsolation: true, nodeIntegration: false | `main.ts` |
+| G-5 | 统一错误码系统 + 错误推断 | `error-handler.ts` |
+| G-6 | 连接状态机 6 状态 + LRU 淘汰 | `connectionPool.ts` |
---
-## 安全合规评估
+## 依赖评估
-| ID | 问题 | 严重性 | 状态 |
-|----|------|--------|------|
-| S-1 | 密码明文存储在 SQLite | 🔴 Critical | ✅ 已修复 (AES-256-GCM) |
-| S-2 | SSH 私钥内容未加密 | 🔴 Critical | 🟡 待实现 (路径不敏感) |
-| S-3 | `sandbox: false` | 🟠 Major | 待优化 |
-| S-4 | `contextIsolation: true` | ✅ 已配置 | - |
-
-### 安全目标 (v1.0.0)
-
-- [x] 实现 AES-256-GCM 加密
-- [x] 主密钥自动管理
-- [ ] 集成系统密钥环 (keytar)
-- [ ] 启用 sandbox 模式
+| 依赖 | 当前 | 最新 | 状态 | 风险 |
+|------|------|------|------|------|
+| `electron` | ^28.3.3 | v33+ | 🔴 严重过时 | 性能、安全、API 兼容 |
+| `better-sqlite3` | ^9.4.0 | v11.x | 🟡 过时 | 性能改进 |
+| `zustand` | ^4.4.7 | v5.x | 🟡 非最新 | 细粒度订阅改进 |
+| `lucide-react` | ^0.294.0 | 0.4xx | 🟡 过时 | 图标缺失 |
+| `socksv5` | ^0.0.6 | — | 🟡 不稳定 | 0.0.x 版本 |
+| `react-router-dom` | ^6.21.0 | 6.x | 🟢 未使用 | 死依赖 |
+| `eslint` | ^8.55.0 | v9.x | 🟡 已停维 | flat config 迁移 |
+| `react` / `react-dom` | ^18.2.0 | 18.3.x | 🟢 稳定 | — |
+| `@xterm/xterm` | ^5.5.0 | 5.5.x | 🟢 最新 | — |
+| `ssh2` | ^1.15.0 | 1.15.x | 🟢 稳定 | — |
---
-## 测试策略
+## 测试评估
-### 测试覆盖率目标
+### 现状
-| 版本 | 单元测试 | 集成测试 | E2E |
-|------|----------|----------|-----|
-| v0.5.0 | 20% | 10% | 5% |
-| v1.0.0 | 60% | 30% | 15% |
+| 测试文件 | 用例数 | 覆盖模块 |
+|----------|--------|----------|
+| `test/stores/tabStore.test.ts` | 15 | tabStore(完整) |
+| `test/stores/connectionPool.test.ts` | 7 | poolStore(仅接口验证) |
+| `test/components/sftp/utils.test.ts` | 12 | sftp/utils.ts(完整) |
+| **总计** | **34** | — |
+
+### 未覆盖的关键模块
+
+| 模块 | 代码行数 | 优先级 | 说明 |
+|------|----------|--------|------|
+| `ssh-service.ts` | 685 | P0 | SSH 连接/Shell/端口转发核心 |
+| `crypto.ts` | ~100 | P0 | 加密/解密必须验证正确性 |
+| `database-service.ts` | 310 | P1 | 数据持久化 |
+| `TerminalView.tsx` | 645 | P1 | 核心终端组件 |
+| `useSFTP.ts` | 510 | P1 | SFTP 全部操作 |
+| `ipc/*.ts` (8个) | ~600 | P1 | IPC 通道处理 |
+| `error-handler.ts` | 330 | P2 | 错误处理工具 |
+| `poolStore.ts` | 402 | P2 | 连接池逻辑 |
+| `lifecycleStore.ts` | 235 | P2 | 生命周期管理 |
+
+**估算覆盖率: ~10-15%**(vitest.config.ts 设定 50% 阈值,实际远未达到)
+
+---
+
+## 安全评估
+
+### 加密实现 ✅ 优秀
+
+| 评估项 | 状态 | 说明 |
+|--------|------|------|
+| AES-256-GCM | ✅ | 认证加密,防篡改 |
+| PBKDF2 密钥派生 | ✅ | 100,000 迭代 |
+| 随机 Salt + IV | ✅ | 每次加密独立 |
+| Master Key 文件权限 | ✅ | 0o600 |
+| Auth Tag 验证 | ✅ | 解密时校验完整性 |
+
+### 安全隐患 ⚠️
+
+| 问题 | 严重性 | 说明 |
+|------|--------|------|
+| 密码可能明文通过 IPC | 🔴 | Session 类型含 password 字段,需确认传输时是否加密 |
+| SSH 私钥通过 IPC 明文 | 🟡 | `sshConnect(config: any)` 私钥内容明文传递 |
+| `sandbox: false` | 🟡 | preload 未启用沙箱 |
+| CSP `unsafe-inline` | 🟡 | 削弱 XSS 防护 |
+| IPC 无输入验证 | 🟡 | 所有 IPC 调用参数无 schema 验证 |
---
## 性能指标
-| 指标 | 当前值 | 目标值 | 说明 |
+| 指标 | 当前值 | 目标值 | 达标 |
|------|--------|--------|------|
-| **冷启动时间** | ~3s | <2s | - |
-| **SSH 连接速度** | ~1s | <500ms | - |
-| **终端输入延迟** | <16ms | <10ms | - |
-| **内存占用** | ~200MB | <150MB | 10 标签并发 |
-| **标签切换延迟** | <50ms | <100ms | ✅ 达标 |
-| **后台连接保持** | 5 个 | - | ✅ 专业功能 |
-| **连接复用率** | >80% | - | 相同配置 |
-| **包体积** | ~120MB | <100MB | - |
+| 冷启动时间 | ~3s | <2s | ❌ |
+| SSH 连接速度 | ~1s | <500ms | ❌ |
+| 终端输入延迟 | <16ms | <10ms | ✅ |
+| 内存占用(10标签) | ~200MB | <150MB | ❌ |
+| 标签切换延迟 | <50ms | <100ms | ✅ |
+| 包体积 | ~120MB | <100MB | ❌ |
---
-## 下一步计划
+## 优化方向与目标
-### v1.0.0 Stable 完成条件
+### v1.1.0 — 代码质量清理 (预计 1 周)
-| 优先级 | 功能 | 状态 |
-|--------|------|------|
-| P0 | 测试框架建立 | 🔴 待开始 |
-| P1 | 文件列表右键菜单 | 🟡 待实现 |
-| P1 | WebGL 渲染优化 | 🟡 待优化 |
-| P2 | sandbox 模式 | 🟡 待优化 |
+**目标**: 清除生产代码中的调试残留,提升代码质量评分至 70+
-### v0.7.0 架构亮点
+| 任务 | 优先级 | 影响文件 | 预计工时 |
+|------|--------|----------|----------|
+| 移除所有 console.log / 调试函数 | P0 | `TerminalView.tsx`, `useSFTP.ts`, `ssh-service.ts` | 4h |
+| 移除 `DEBUG = true` 硬编码 | P0 | `TerminalView.tsx:16` | 0.5h |
+| 移除 Mock 数据 | P0 | `useSFTP.ts:154-161` | 1h |
+| 补全 SFTP 上传功能 | P0 | `useSFTP.ts` | 4h |
+| 补全 disconnect() 资源释放 | P1 | `useSFTP.ts:359-373` | 2h |
+| Math.random → uuid | P1 | `TerminalView.tsx` | 1h |
+| IPC 通道名引用常量 | P2 | `preload.ts` | 2h |
+| 移除未使用依赖 react-router-dom | P2 | `package.json` | 0.5h |
+
+**验收标准**:
+- `grep -r "console.log" src/ electron/` 返回 0 结果
+- `grep -r "DEBUG = true" src/` 返回 0 结果
+- SFTP 上传功能端到端可用
+
+### v1.2.0 — 组件拆分重构 (预计 1.5 周)
+
+**目标**: TerminalView 拆分为可维护的模块,架构评分提升至 80+
+
+| 任务 | 优先级 | 说明 |
+|------|--------|------|
+| TerminalView → useTerminal Hook | P0 | 提取连接管理、Shell 数据处理 |
+| TerminalView → useTerminalSnapshot Hook | P0 | 提取快照保存/恢复逻辑 |
+| TerminalView → useZmodem Hook | P1 | 提取 rz/sz 文件传输逻辑 |
+| useSFTP → useSFTPNavigation + useSFTPTransfer | P1 | 分离导航和传输职责 |
+| App.tsx → 导入/导出逻辑抽到 service | P2 | 分离业务逻辑 |
+| Store 解耦 | P2 | lifecycleStore 不直接操作 poolStore |
+
+**验收标准**:
+- 单文件不超过 300 行
+- Hook 职责单一,可独立测试
+
+### v1.3.0 — 测试覆盖达标 (预计 2 周)
+
+**目标**: 核心模块测试覆盖率 60%+,测试评分提升至 50+
+
+| 阶段 | 目标模块 | 用例目标 |
+|------|----------|----------|
+| 第一批(P0) | `crypto.ts`, `ssh-service.ts`(mock ssh2) | 30+ |
+| 第二批(P1) | `database-service.ts`, `error-handler.ts`, `poolStore.ts` | 40+ |
+| 第三批(P1) | `IPC handlers`(8个), `TerminalView`(组件测试) | 50+ |
+| 第四批(P2) | `useSFTP`, `lifecycleStore`, `tabStore`补充 | 30+ |
+
+**验收标准**:
+- `npm test -- --coverage` 总覆盖率 ≥ 50%
+- 核心模块(crypto, ssh-service) 覆盖率 ≥ 80%
+
+### v1.4.0 — 依赖升级 + 安全加固 (预计 1 周)
+
+**目标**: 依赖更新到稳定版本,安全评分提升至 75+
+
+| 任务 | 优先级 | 风险 |
+|------|--------|------|
+| Electron v28 → v33+ | P0 | Breaking changes 需逐一适配 |
+| better-sqlite3 v9 → v11 | P0 | API 有变化 |
+| ESLint v8 → v9 flat config | P1 | 配置迁移 |
+| Zustand v4 → v5 | P2 | 订阅 API 变化 |
+| 启用 sandbox 模式 | P1 | preload 需适配 |
+| CSP 移除 unsafe-inline | P1 | Tailwind 需配置 |
+| IPC 参数 schema 验证 | P2 | 引入 zod 或类似库 |
+
+### v1.5.0 — 功能补全 + 性能优化 (预计 2 周)
+
+**目标**: 补全缺失功能,性能指标全面达标
+
+| 任务 | 优先级 | 说明 |
+|------|--------|------|
+| SFTP 拖拽上传/下载 | P1 | 界面就绪,补全事件处理 |
+| SFTP 断点续传 | P2 | 大文件传输可靠性 |
+| 会话分组树形显示 | P2 | 侧边栏优化 |
+| 终端分屏 | P3 | 水平/垂直分屏 |
+| 安装包体积优化 | P1 | asar + tree-shaking + 依赖瘦身 |
+| 冷启动优化 | P1 | 延迟加载非核心模块 |
+
+---
+
+## 里程碑总览
```
-专业级连接管理
-├── 连接状态机 (6 个状态)
-├── LRU 淘汰策略
-├── 终端快照机制
-├── 自动保活 & 超时
-└── 连接复用优化
+v1.1.0 代码质量清理 (1 周) → 代码质量 45→70
+v1.2.0 组件拆分重构 (1.5 周) → 架构 72→85
+v1.3.0 测试覆盖达标 (2 周) → 测试 15→50
+v1.4.0 依赖升级+安全 (1 周) → 安全 55→75
+v1.5.0 功能补全+性能 (2 周) → 功能 82→95
-设计原则
-├── 资源隔离:每个标签独立连接实例
-├── 性能优化:快照避免重复渲染
-├── 资源控制:连接池上限管理
-└── 用户体验:无缝标签切换
+总计: ~7.5 周 → 综合评分 58→80+
```
+
+### 成功指标
+
+| 指标 | v1.0 当前 | v1.5 目标 |
+|------|-----------|-----------|
+| 综合评分 | 58/100 | 80+/100 |
+| 测试覆盖率 | ~10% | ≥50% |
+| 代码质量(零console.log) | 50+ 处 | 0 处 |
+| 单文件最大行数 | 685 | ≤300 |
+| Electron 版本 | v28 | v33+ |
+| 安全评分 | 55 | 75+ |
+| 包体积 | ~120MB | <100MB |
diff --git a/ROADMAP.md b/ROADMAP.md
index 744c690..caa760e 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -19,250 +19,277 @@
| v0.9.0 | **Optimization** | P0/P1 全面优化 | ✅ 已完成 |
| v0.10.0 | **v0.3.0-release** | 核心功能实现 | ✅ 已完成 |
| v1.0.0 | **Stable** | 生产可用 | ✅ 已完成 |
+| **v1.1.0** | **Cleanup** | **代码质量清理** | 🔄 进行中 |
+| **v1.2.0** | **Refactor** | **组件拆分重构** | 📋 规划中 |
+| **v1.3.0** | **Testing** | **测试覆盖达标** | 📋 规划中 |
+| **v1.4.0** | **Upgrade** | **依赖升级+安全加固** | 📋 规划中 |
+| **v1.5.0** | **Polish** | **功能补全+性能优化** | 📋 规划中 |
+| v2.0.0 | **Professional** | 专业版发布 | 📋 远期规划 |
---
-## v0.5.0 Pre-Stable ✅
+## v1.1.0 代码质量清理 🔄
-**完成日期**: 2026-04-05
+**目标**: 清除生产代码中的调试残留,补全 SFTP 核心功能
+**预计**: 1 周
+**评分目标**: 代码质量 45→70
-### ✅ 已完成功能清单
+### 任务清单
-#### SFTP 传输队列优化
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 传输队列显示 | `SFTPView.tsx` | 显示进行中的上传/下载任务 |
-| 传输历史记录 | `SFTPView.tsx` | 显示最近完成的传输任务 |
-| 可收起面板 | `SFTPView.tsx` | 点击展开/收起传输面板 |
-| 多文件上传队列 | `SFTPView.tsx` | 逐个上传并显示各任务进度 |
-| Downloads 目录 | `SFTPView.tsx` | 跨平台默认下载路径 |
-| 移除删除按钮 | `SFTPView.tsx` | 简化界面 |
+| # | 任务 | 优先级 | 文件 | 状态 |
+|---|------|--------|------|------|
+| 1 | 移除所有 console.log 和彩色调试函数 | P0 | `TerminalView.tsx`, `useSFTP.ts`, `ssh-service.ts` | ⬜ |
+| 2 | 移除 `DEBUG = true` 硬编码 | P0 | `TerminalView.tsx:16` | ⬜ |
+| 3 | 移除 Mock 数据残留 | P0 | `useSFTP.ts:154-161` | ⬜ |
+| 4 | 补全 SFTP 上传 IPC 实现 | P0 | `useSFTP.ts:399`, `sftp.ipc.ts` | ⬜ |
+| 5 | 补全 disconnect() 资源释放 | P1 | `useSFTP.ts:359-373` | ⬜ |
+| 6 | Math.random → uuid 生成 ID | P1 | `TerminalView.tsx:383,463` | ⬜ |
+| 7 | IPC 通道名引用 IPC_CHANNELS 常量 | P2 | `preload.ts` | ⬜ |
+| 8 | 移除未使用依赖 react-router-dom | P2 | `package.json` | ⬜ |
+| 9 | 替换重复的彩色日志函数为统一 logger | P2 | `TerminalView.tsx`, `useSFTP.ts` | ⬜ |
+| 10 | 修复 `if (false)` 等无用代码 | P2 | `TerminalView.tsx:50` | ⬜ |
+
+### 验收标准
+
+```bash
+# 零调试残留
+grep -r "console.log" src/ electron/ | wc -l # → 0
+grep -r "DEBUG = true" src/ | wc -l # → 0
+grep -r "logHeader\|logInfo\|logSuccess\|logError\|logWarning" src/ electron/ | wc -l # → 0
+
+# SFTP 上传功能可用
+# 手动测试:连接 → SFTP → 上传文件 → 验证远端文件存在
+```
---
-## v0.6.0 Pre-Stable ✅
+## v1.2.0 组件拆分重构 📋
-**完成日期**: 2026-04-05
+**目标**: 终端组件拆分为可维护的 Hook 体系
+**预计**: 1.5 周
+**评分目标**: 架构 72→85
-### ✅ 已完成功能清单
+### 拆分计划
-#### 终端 rz/sz 支持
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| rz 命令拦截 | `TerminalView.tsx` | 检测 rz 并打开文件选择器 |
-| sz 文件接收 | `TerminalView.tsx` | 捕获 Zmodem 数据并保存 |
-| 文件读写 API | `preload.ts`, `main.ts` | 支持 rz 上传和 sz 下载 |
+#### TerminalView.tsx (645行) → 拆分
+
+```
+src/components/terminal/TerminalView.tsx (~150行) 纯渲染层
+src/hooks/useTerminal.ts (~200行) 终端初始化 + 数据流
+src/hooks/useTerminalConnection.ts (~150行) SSH 连接管理
+src/hooks/useTerminalSnapshot.ts (~100行) 快照保存/恢复
+src/hooks/useZmodem.ts (~100行) rz/sz 文件传输
+```
+
+#### useSFTP.ts (510行) → 拆分
+
+```
+src/hooks/useSFTPNavigation.ts (~200行) 本地/远程目录导航
+src/hooks/useSFTPTransfer.ts (~200行) 上传/下载/传输队列
+src/hooks/useSFTPConnection.ts (~100行) SFTP 连接管理
+```
+
+#### App.tsx (258行) → 业务逻辑外提
+
+```
+src/components/App.tsx (~150行) 纯 UI 编排
+src/services/sessionImport.ts (~80行) 导入/导出逻辑
+```
+
+### Store 解耦
+
+```
+当前: lifecycleStore → 直接调用 poolStore.getState()
+目标: 引入 ConnectionFacade 统一接口,Store 通过事件通信
+```
+
+### 验收标准
+
+- 单文件不超过 300 行
+- Hook 可独立导入、独立测试
+- 现有功能无回归
---
-## v0.7.0 Professional ✅
+## v1.3.0 测试覆盖达标 📋
-**完成日期**: 2026-04-05
+**目标**: 核心模块测试覆盖率 ≥60%,总覆盖率 ≥50%
+**预计**: 2 周
+**评分目标**: 测试 15→50
-### ✅ 已完成功能清单
+### 测试批次
-#### 专业连接管理架构
+| 批次 | 目标模块 | 用例目标 | 优先级 |
+|------|----------|----------|--------|
+| 1 | `crypto.ts` (加密/解密正确性) | 15+ | P0 |
+| 2 | `ssh-service.ts` (mock ssh2) | 20+ | P0 |
+| 3 | `database-service.ts` (CRUD) | 15+ | P1 |
+| 4 | `error-handler.ts` (错误推断) | 10+ | P1 |
+| 5 | `poolStore.ts` + `lifecycleStore.ts` | 20+ | P1 |
+| 6 | `IPC handlers` (8个模块) | 25+ | P1 |
+| 7 | `TerminalView` 组件测试 | 10+ | P2 |
+| 8 | `useSFTP` hooks 测试 | 15+ | P2 |
+| **总计** | | **130+** | |
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 连接状态机 | `connectionPool.ts` | disconnected/connecting/connected/background/suspended |
-| 连接池管理 | `connectionPool.ts` | 最大 10 并发,LRU 淘汰策略 |
-| 后台连接保持 | `connectionPool.ts` | 最大 5 个后台连接,空闲 5 分钟挂起 |
-| 自动保活机制 | `connectionPool.ts` | 每分钟发送心跳包 |
-| 连接复用 | `connectionPool.ts` | 相同配置标签共享 SSH 连接 |
-| 终端快照 | `terminalSnapshotStore.ts` | 切换标签保存/恢复终端内容 |
-| 快照恢复 | `TerminalView.tsx` | 快速恢复显示,避免黑屏 |
-| 挂起恢复 UI | `TerminalView.tsx` | 手动恢复或重新连接选项 |
-| 连接状态指示 | `TerminalView.tsx` | 实时显示连接状态(绿/蓝/黄/红) |
-| 专业设置面板 | `SettingsView.tsx` | 可配置连接池参数 |
+### 验收标准
-#### 多标签连接隔离
-
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 独立连接实例 | `tabStore.ts` | 每个标签独立的 connectionInstance |
-| 标签切换优化 | `TabContent.tsx` | opacity 过渡,保持组件实例 |
-| 连接引用计数 | `connectionPool.ts` | 正确管理连接生命周期 |
-| 关闭自动断开 | `TabBar.tsx` | 标签关闭时释放对应连接 |
+```bash
+npm test -- --coverage
+# Statements ≥ 50%
+# Branches ≥ 40%
+# Functions ≥ 50%
+# Lines ≥ 50%
+```
---
-## v0.8.0 Modular ✅
+## v1.4.0 依赖升级 + 安全加固 📋
-**完成日期**: 2026-04-05
+**目标**: 依赖更新到最新稳定版,安全漏洞清零
+**预计**: 1 周
+**评分目标**: 安全 55→75, 依赖 50→80
-### ✅ 已完成架构重构清单
+### 依赖升级
-#### IPC Handler 分层
+| 依赖 | 当前 | 目标 | 风险 |
+|------|------|------|------|
+| `electron` | v28 | v33+ | 高 - Breaking changes |
+| `better-sqlite3` | v9 | v11 | 中 - API 变化 |
+| `zustand` | v4 | v5 | 低 - 订阅 API 变化 |
+| `lucide-react` | 0.294 | 0.4xx | 低 - 图标名可能有变化 |
+| `eslint` | v8 | v9 | 中 - flat config 迁移 |
-| 模块 | 文件 | 说明 |
-|------|------|------|
-| SSH IPC | `electron/ipc/ssh.ipc.ts` | 连接/断开/exec/Shell/端口转发 |
-| SFTP IPC | `electron/ipc/sftp.ipc.ts` | SFTP 操作/传输进度 |
-| 会话 IPC | `electron/ipc/session.ipc.ts` | CRUD 操作 |
-| 设置 IPC | `electron/ipc/settings.ipc.ts` | 读写设置 |
-| 对话框 IPC | `electron/ipc/dialog.ipc.ts` | 文件对话框 |
-| 文件 IPC | `electron/ipc/file.ipc.ts` | 本地文件操作 |
-| Zmodem IPC | `electron/ipc/zmodem.ipc.ts` | rz/sz 传输 |
-| 应用 IPC | `electron/ipc/app.ipc.ts` | 版本/路径信息 |
+### 安全加固
-#### 共享类型统一
-
-| 类型 | 文件 | 说明 |
-|------|------|------|
-| Session 类型 | `shared/types/session.types.ts` | 会话配置、认证类型 |
-| Connection 类型 | `shared/types/connection.types.ts` | 连接池、连接状态 |
-| SFTP 类型 | `shared/types/sftp.types.ts` | 文件项、传输任务 |
-| IPC 类型 | `shared/types/ipc.types.ts` | IPC 通道常量 |
-
-#### 连接池 Store 拆分
-
-| Store | 文件 | 说明 |
-|------|------|------|
-| Pool Store | `src/stores/connection/poolStore.ts` | 连接池核心:创建/获取/释放 |
-| Lifecycle Store | `src/stores/connection/lifecycleStore.ts` | 状态机、超时、事件 |
-| Store Hooks | `src/stores/connection/storeHooks.ts` | 组合接口 |
-
-#### SFTP 组件拆分
-
-| 组件 | 文件 | 说明 |
-|------|------|------|
-| Breadcrumb | `src/components/sftp/Breadcrumb.tsx` | 路径导航 |
-| SortHeader | `src/components/sftp/SortHeader.tsx` | 列排序 |
-| FileRow | `src/components/sftp/FileRow.tsx` | 文件行渲染 |
-| ContextMenu | `src/components/sftp/ContextMenu.tsx` | 右键菜单 |
-| TransferItem | `src/components/sftp/TransferItem.tsx` | 传输任务项 |
-| ConnectionSelector | `src/components/sftp/ConnectionSelector.tsx` | 服务器选择 |
+| 任务 | 说明 |
+|------|------|
+| 启用 sandbox 模式 | preload 适配 |
+| CSP 移除 unsafe-inline | Tailwind nonce 配置 |
+| IPC 参数验证 | zod schema |
+| 密码 IPC 传输审查 | 确保加密后传输 |
+| 审查 socksv5 安全性 | 评估是否替换 |
---
-## v0.9.0 Optimization ✅
+## v1.5.0 功能补全 + 性能优化 📋
-**完成日期**: 2026-04-05
+**目标**: 补全缺失功能,性能指标全面达标
+**预计**: 2 周
+**评分目标**: 功能 82→95, 综合 80+
-### ✅ 已完成功能清单
+### 功能补全
-#### 测试框架建立
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| Vitest 配置 | `vitest.config.ts` | 测试环境配置 |
-| 测试设置 | `test/setup.ts` | Electron API mock |
-| TabStore 测试 | `test/stores/tabStore.test.ts` | 16 个测试用例 |
-| ConnectionPool 测试 | `test/stores/connectionPool.test.ts` | 8 个测试用例 |
-| SFTP Utils 测试 | `test/components/sftp/utils.test.ts` | 14 个测试用例 |
+| 功能 | 优先级 | 说明 |
+|------|--------|------|
+| SFTP 拖拽上传/下载 | P1 | 界面已就绪,补全 drag/drop 事件 |
+| SFTP 断点续传 | P2 | 大文件传输可靠性 |
+| 会话分组树形显示 | P2 | 侧边栏分组 + 文件夹 |
+| 终端分屏 | P3 | 水平/垂直分屏 |
+| 命令片段(Snippets) | P3 | 常用命令快速执行 |
+| 同步功能 | P3 | 多设备会话同步 |
-#### SFTP 右键菜单完善
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 新建文件夹 | `SFTPView.tsx` | 本地新建文件夹 |
-| 复制路径 | `SFTPView.tsx` | 复制文件完整路径 |
-| 查看属性 | `SFTPView.tsx` | 显示文件详情 |
-| sftpMkdir IPC | `sftp.ipc.ts` | 远程创建目录支持 |
+### 性能优化
-#### WebGL 渲染优化
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| WebGL Addon | `TerminalView.tsx` | GPU 加速渲染 |
-| 自动降级 | `TerminalView.tsx` | WebGL 不可用时降级 |
-
-#### 会话导入完善
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| JSON 格式导入 | `App.tsx` | 支持数组和对象格式 |
-| SSH Config 导入 | `App.tsx` | 支持 Host/HostName/User |
-| 批量创建 | `App.tsx` | 自动创建所有会话 |
+| 指标 | 当前 | 目标 | 方案 |
+|------|------|------|------|
+| 冷启动 | ~3s | <2s | 延迟加载非核心模块 |
+| 包体积 | ~120MB | <100MB | asar + tree-shaking |
+| 内存(10标签) | ~200MB | <150MB | 连接池优化 + 终端回收 |
+| SSH 连接 | ~1s | <500ms | 连接预热 |
---
-## v0.10.0 v0.3.0-release ✅
+## 远期规划 (v2.0.0)
-**完成日期**: 2026-04-06
+### 专业版特性
-### ✅ 已完成功能清单
-
-#### SSH 终端核心功能
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 密码认证 | `ssh-service.ts` | 用户名密码连接 |
-| 密钥认证 | `ssh-service.ts` | RSA/ED25519 私钥认证 |
-| XTerm.js 终端 | `TerminalView.tsx` | 高性能终端仿真 |
-| 多主题配色 | `terminal.ts` | Dracula/Monokai/Solarized/One Dark |
-| IP 高亮显示 | `TerminalView.tsx` | Last login IP 绿色高亮 |
-| 端口转发 | `PortForwardView.tsx` | 本地/远程/SOCKS5 动态代理 |
-
-#### SFTP 文件管理
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 双栏文件管理 | `SFTPView.tsx` | 本地/远程双栏对比 |
-| 上传下载 | `useSFTP.ts` | 文件传输队列 |
-| 传输进度 | `TransferPanel.tsx` | 实时进度显示 |
-| 服务器选择 | `ConnectionSelector.tsx` | 快速选择已保存会话 |
-
-#### 架构改进
-| 功能 | 文件 | 说明 |
-|------|------|------|
-| 模块化 IPC | `electron/ipc/*.ts` | 8 个独立 IPC 模块 |
-| 连接池管理 | `poolStore.ts` | 连接复用和生命周期管理 |
-| 统一日志 | `logger.ts` | 彩色高亮调试日志 |
-| 错误处理 | `error-handler.ts` | 统一错误边界处理 |
+- 插件系统 — 支持第三方扩展
+- 主题编辑器 — 自定义配色方案
+- 脚本录制/回放 — 操作自动化
+- 协作共享 — 团队会话管理
+- 云同步 — 加密会话配置同步
+- API 网关 — 命令行/CI 集成
+- 容器管理 — Docker/Podman 集成
---
-## v1.0.0 Stable - 生产可用 ✅
+## 已完成版本
+
+
+展开查看历史版本
+
+### v1.0.0 Stable - 生产可用 ✅
**状态**: 已完成
-### 功能完成清单
+#### 功能完成清单
-#### SSH 终端
+##### SSH 终端
- ✅ 密码/密钥认证
- ✅ XTerm.js 高性能终端
- ✅ 多主题配色方案
- ✅ IP 地址高亮显示
-#### SFTP 管理
+##### SFTP 管理
- ✅ 双栏文件管理器
- ✅ 上传/下载文件
- ✅ 传输队列管理
- 🟡 拖拽上传下载 (界面就绪,待完善)
- 📋 断点续传 (规划中)
-#### 端口转发
+##### 端口转发
- ✅ 本地端口转发
- ✅ 远程端口转发
- ✅ 动态 SOCKS5 代理
- ✅ 转发规则管理
-#### 架构特性
+##### 架构特性
- ✅ IPC Handler 模块化
- ✅ 共享类型定义
- ✅ 连接池 Store 拆分
- ✅ 统一日志系统
----
+### v0.10.0 v0.3.0-release ✅
-## 开发优先级
+**完成日期**: 2026-04-06
-```
-v0.6.0 完成清单 ✅
+- ✅ SSH 终端核心功能(密码/密钥认证、XTerm.js、多主题、IP高亮、端口转发)
+- ✅ SFTP 文件管理(双栏、上传下载、传输队列、服务器选择)
+- ✅ 架构改进(模块化 IPC、连接池管理、统一日志、错误处理)
-v1.0.0 开发顺序:
-├── 1. 测试框架建立 (P0)
-├── 2. 文件列表右键菜单 (P1)
-├── 3. WebGL 渲染优化 (P1)
-└── 4. 会话导入完整实现 (P1)
-```
+### v0.9.0 Optimization ✅
----
+**完成日期**: 2026-04-05
-## 里程碑检查点
+- ✅ 测试框架建立(Vitest + 38 测试用例)
+- ✅ SFTP 右键菜单(新建文件夹/复制路径/属性)
+- ✅ WebGL 终端渲染优化
+- ✅ 会话导入完整实现
-### v1.0.0 Stable 完成条件
+### v0.8.0 Modular ✅
-- [x] 测试框架建立 (vitest + 38 测试用例)
-- [x] 文件列表右键菜单 (新建/复制/属性)
-- [x] WebGL 终端渲染优化
-- [x] 会话导入完整实现
-- [ ] 无 critical/major 级别 bug
-- [ ] 打包后可在 macOS/Windows 运行
-- [ ] 性能指标达标
+**完成日期**: 2026-04-05
+
+- ✅ IPC Handler 分层(8 个独立模块)
+- ✅ 共享类型统一
+- ✅ 连接池 Store 拆分
+- ✅ SFTP 组件拆分
+
+### v0.7.0 Professional ✅
+
+**完成日期**: 2026-04-05
+
+- ✅ 连接状态机(6 个状态)
+- ✅ 连接池管理(LRU淘汰、保活、超时)
+- ✅ 终端快照机制
+- ✅ 多标签连接隔离
+
+### v0.6.0 ~ v0.1.0 ✅
+
+- ✅ rz/sz 文件传输
+- ✅ SFTP 传输队列优化
+- ✅ AES-256-GCM 加密存储
+- ✅ 端口转发
+- ✅ 功能骨架 + 核心 SSH
+
+
diff --git a/TDD_PLAN.md b/TDD_PLAN.md
index 948373b..dec1028 100644
--- a/TDD_PLAN.md
+++ b/TDD_PLAN.md
@@ -1,489 +1,363 @@
-# TDD_PLAN.md - 测试计划
+# TDD_PLAN.md - 测试驱动开发计划
-本文档规划 OpsXShell 的测试策略,采用 **先有后优** 的开发理念。
+本文档规划 OpsXShell 的测试策略,覆盖从单元测试到 E2E 测试的完整体系。
-**核心理念**: 先确保功能完整可用,再逐步建立自动化测试覆盖
+---
+
+## 当前状态
+
+| 指标 | 当前值 | 目标值 |
+|------|--------|--------|
+| 测试文件数 | 3 | 15+ |
+| 测试用例数 | 34 | 150+ |
+| 估算覆盖率 | ~10% | ≥50% |
+| 核心模块覆盖 | 0% | ≥80% |
+
+### 已有测试
+
+| 测试文件 | 用例数 | 覆盖模块 | 质量 |
+|----------|--------|----------|------|
+| `test/stores/tabStore.test.ts` | 15 | tabStore | ✅ 完整 |
+| `test/stores/connectionPool.test.ts` | 7 | poolStore | 🟡 仅接口验证 |
+| `test/components/sftp/utils.test.ts` | 12 | sftp/utils | ✅ 完整 |
---
## 测试策略
-### 当前阶段 (v1.0.0)
-
```
-功能实现 → 手动验证 → 测试框架 → 单元测试 → 集成测试
- ↑__________________________________________________|
+v1.3.0 测试计划
+├── P0: 核心安全模块(crypto, ssh-service)
+├── P1: 数据层(database, error-handler, stores)
+├── P1: IPC 通信层(8 个 IPC Handler)
+├── P2: UI 层(TerminalView, useSFTP hooks)
+└── P3: E2E 集成(Playwright)
```
-**原则**:
-1. 功能优先:先实现并手动验证功能可用
-2. 测试跟进:功能稳定后建立自动化测试
-3. 逐步覆盖:从核心模块开始扩展测试范围
-4. 集成验证:确保 IPC 通信和端到端流程正确
+### 原则
+
+1. **安全先行**: 加密/解密模块必须 100% 测试覆盖
+2. **核心优先**: SSH 连接逻辑是应用核心,优先覆盖
+3. **可 mock 性**: 所有外部依赖(ssh2, better-sqlite3, electron)必须可 mock
+4. **独立性**: 每个测试独立运行,不依赖外部状态
+5. **快速反馈**: 单元测试 < 5s,集成测试 < 30s
---
-## 第一阶段:测试框架建立 (P0)
+## 测试环境配置
-### 1.1 安装测试依赖
-
-```bash
-# Vitest + React Testing Library
-npm install -D vitest @vitest/ui jsdom @testing-library/react @testing-library/jest-dom
-
-# Playwright E2E
-npm install -D @playwright/test
-npx playwright install chromium
-```
-
-### 1.2 配置文件
+### 已有配置
```typescript
// vitest.config.ts
-import { defineConfig } from 'vitest/config'
-
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
- setupFiles: ['./tests/setup.ts'],
+ setupFiles: ['./test/setup.ts'],
coverage: {
provider: 'v8',
- reporter: ['text', 'html'],
+ reporter: ['text', 'html', 'lcov'],
+ thresholds: {
+ statements: 50, // 当前远未达到
+ branches: 40,
+ functions: 50,
+ lines: 50,
+ },
},
},
})
```
+### Mock 策略
+
```typescript
-// tests/setup.ts
-import '@testing-library/jest-dom'
+// test/setup.ts 已有:
+// - window.electronAPI 完整 mock
+// - localStorage mock
-// Mock electron API
-const mockElectronAPI = {
- sshConnect: vi.fn(),
- sshDisconnect: vi.fn(),
- sshCreateShell: vi.fn(),
- sshShellWrite: vi.fn(),
- sshShellResize: vi.fn(),
- sessionGetAll: vi.fn(),
- sessionGetById: vi.fn(),
- sessionCreate: vi.fn(),
- sessionUpdate: vi.fn(),
- sessionDelete: vi.fn(),
- sftpConnect: vi.fn(),
- sftpListDirectory: vi.fn(),
- sftpUpload: vi.fn(),
- sftpDownload: vi.fn(),
- onShellData: vi.fn(),
- removeAllListeners: vi.fn(),
-}
-
-window.electronAPI = mockElectronAPI as any
+// 需要新增:
+// - ssh2 Client mock
+// - better-sqlite3 mock
+// - zmodem-ts mock
```
---
-## 第二阶段:单元测试 (P0)
+## P0: 核心模块测试(第一批)
-### 2.1 Store 测试
+### 1. crypto.ts 测试 — 加密/解密正确性
-#### tabStore.test.ts
+**文件**: `test/services/crypto.test.ts`
+**用例目标**: 15+
```typescript
-import { describe, it, expect, beforeEach } from 'vitest'
-import { useTabStore } from '../../src/stores/tabStore'
-
-describe('useTabStore', () => {
- beforeEach(() => {
- // Reset store
- useTabStore.setState({
- tabs: [{ id: 'welcome', title: '欢迎', type: 'welcome', isActive: true }],
- activeTabId: 'welcome',
- })
+describe('Crypto Service', () => {
+ describe('encrypt / decrypt', () => {
+ it('应正确加密并解密明文字符串')
+ it('应正确加密并解密空字符串')
+ it('应正确加密并解密特殊字符和 Unicode')
+ it('每次加密应生成不同的密文(随机 IV)')
+ it('密文篡改后解密应失败(Auth Tag 验证)')
+ it('错误密钥解密应失败')
})
- describe('addTab', () => {
- it('should add a new terminal tab', () => {
- const { addTab } = useTabStore.getState()
- addTab({ title: 'Test', type: 'terminal' })
-
- const { tabs } = useTabStore.getState()
- expect(tabs).toHaveLength(2)
- expect(tabs[1].title).toBe('Test')
- })
-
- it('should activate new tab', () => {
- const { addTab } = useTabStore.getState()
- addTab({ title: 'Test', type: 'terminal' })
-
- const { activeTabId } = useTabStore.getState()
- expect(activeTabId).toBe('tab-1')
- })
-
- it('should not duplicate settings tab', () => {
- const { addTab } = useTabStore.getState()
- addTab({ title: '设置', type: 'settings' })
- addTab({ title: '设置2', type: 'settings' })
-
- const { tabs } = useTabStore.getState()
- expect(tabs.filter(t => t.type === 'settings')).toHaveLength(1)
- })
+ describe('deriveKey', () => {
+ it('相同密码和 salt 应派生相同密钥')
+ it('不同 salt 应派生不同密钥')
+ it('应使用 100,000 次 PBKDF2 迭代')
})
- describe('closeTab', () => {
- it('should close tab and activate next', () => {
- const { addTab, closeTab, tabs } = useTabStore.getState()
- addTab({ title: 'Tab1', type: 'terminal' })
- const tabToClose = tabs[1].id
- closeTab(tabToClose)
-
- const { tabs: newTabs } = useTabStore.getState()
- expect(newTabs).toHaveLength(1)
- })
-
- it('should not close last tab', () => {
- const { closeTab, tabs } = useTabStore.getState()
- closeTab(tabs[0].id)
-
- const { tabs: newTabs } = useTabStore.getState()
- expect(newTabs).toHaveLength(1)
- })
- })
-
- describe('connectionStatus', () => {
- it('should update tab connection status', () => {
- const { addTab, updateTabStatus } = useTabStore.getState()
- addTab({ title: 'SSH', type: 'terminal' })
- const tabId = useTabStore.getState().tabs[1].id
-
- updateTabStatus(tabId, 'connected')
-
- const { tabs } = useTabStore.getState()
- expect(tabs.find(t => t.id === tabId)?.connectionStatus).toBe('connected')
- })
+ describe('generateSalt / generateIV', () => {
+ it('salt 应为 32 字节随机值')
+ it('IV 应为 12 字节随机值(GCM 推荐)')
+ it('每次生成的值应不同')
})
})
```
-#### connectionStore.test.ts
+### 2. ssh-service.ts 测试 — SSH 连接逻辑
+
+**文件**: `test/services/ssh-service.test.ts`
+**用例目标**: 20+
+**Mock**: ssh2 Client
```typescript
-import { describe, it, expect, beforeEach, vi } from 'vitest'
-import { useConnectionStore } from '../../src/stores/connectionStore'
-
-describe('useConnectionStore', () => {
- beforeEach(() => {
- useConnectionStore.setState({ sessions: [] })
- vi.clearAllMocks()
- })
-
- describe('addSession', () => {
- it('should call sessionCreate API', async () => {
- window.electronAPI.sessionCreate.mockResolvedValue({
- success: true,
- session: { id: 'test-1', name: 'Test', host: 'localhost' },
- })
-
- const { addSession } = useConnectionStore.getState()
- await addSession({
- name: 'Test',
- host: 'localhost',
- port: 22,
- username: 'user',
- authType: 'password',
- })
-
- expect(window.electronAPI.sessionCreate).toHaveBeenCalled()
- })
- })
-
- describe('removeSession', () => {
- it('should remove session from state', async () => {
- useConnectionStore.setState({
- sessions: [{ id: 'test-1', name: 'Test', host: 'localhost' }],
- })
-
- const { removeSession } = useConnectionStore.getState()
- await removeSession('test-1')
-
- const { sessions } = useConnectionStore.getState()
- expect(sessions).toHaveLength(0)
- })
- })
-})
-```
-
-### 2.2 组件测试
-
-#### TerminalView.test.tsx
-
-```typescript
-import { describe, it, expect, vi, beforeEach } from 'vitest'
-import { render, screen, fireEvent } from '@testing-library/react'
-import TerminalView from '../../src/components/TerminalView'
-
-// Mock xterm
-vi.mock('@xterm/xterm', () => ({
- Terminal: vi.fn().mockImplementation(() => ({
- onData: vi.fn(),
- onResize: vi.fn(),
- open: vi.fn(),
- write: vi.fn(),
- dispose: vi.fn(),
- cols: 80,
- rows: 24,
+// Mock ssh2
+vi.mock('ssh2', () => ({
+ Client: vi.fn().mockImplementation(() => ({
+ connect: vi.fn(),
+ on: vi.fn(),
+ end: vi.fn(),
+ shell: vi.fn(),
+ forwardOut: vi.fn(),
+ forwardIn: vi.fn(),
+ sftp: vi.fn(),
})),
}))
-vi.mock('@xterm/addon-fit', () => ({
- FitAddon: vi.fn().mockImplementation(() => ({
- fit: vi.fn(),
- loadAddon: vi.fn(),
+describe('SSH Service', () => {
+ describe('connect', () => {
+ it('应使用密码认证连接')
+ it('应使用私钥认证连接')
+ it('应使用 SSH Agent 认证连接')
+ it('连接失败应返回错误')
+ it('连接超时应返回超时错误')
+ it('重复连接同一主机应复用')
+ })
+
+ describe('createShell', () => {
+ it('应创建交互式 Shell')
+ it('应传入终端尺寸 cols/rows')
+ it('Shell 创建失败应返回错误')
+ })
+
+ describe('disconnect', () => {
+ it('应正确关闭连接')
+ it('应清理所有 Shell 会话')
+ it('应清理端口转发')
+ })
+
+ describe('portForward', () => {
+ it('应创建本地端口转发')
+ it('应创建远程端口转发')
+ it('应创建 SOCKS5 动态代理')
+ it('端口被占用应返回错误')
+ })
+
+ describe('connectionPool', () => {
+ it('不应超过最大连接数限制')
+ it('空闲连接应被自动回收')
+ it('LRU 淘汰策略应正确工作')
+ })
+})
+```
+
+---
+
+## P1: 数据层 + Store 测试(第二批)
+
+### 3. database-service.ts 测试
+
+**文件**: `test/services/database.test.ts`
+**用例目标**: 15+
+
+```typescript
+describe('Database Service', () => {
+ describe('Session CRUD', () => {
+ it('应创建新会话并返回 ID')
+ it('应获取所有会话列表')
+ it('应根据 ID 获取单个会话')
+ it('应更新会话字段')
+ it('应删除会话')
+ it('密码字段应加密存储')
+ it('读取时密码字段应解密')
+ })
+
+ describe('Settings', () => {
+ it('应保存和读取设置')
+ it('未设置的键应返回默认值')
+ it('应支持复杂对象类型设置')
+ })
+
+ describe('数据完整性', () => {
+ it('数据库文件不存在应自动创建')
+ it('Schema 版本升级应自动迁移')
+ })
+})
+```
+
+### 4. error-handler.ts 测试
+
+**文件**: `test/utils/error-handler.test.ts`
+**用例目标**: 10+
+
+```typescript
+describe('Error Handler', () => {
+ describe('inferErrorCode', () => {
+ it('应从 ECONNREFUSED 推断连接错误')
+ it('应从 ETIMEDOUT 推断超时错误')
+ it('应从 auth 推断认证错误')
+ it('应从 ENOENT 推断文件不存在错误')
+ it('未知错误应返回通用错误码')
+ })
+
+ describe('withErrorHandling', () => {
+ it('应包装异步函数并捕获错误')
+ it('应返回统一错误格式')
+ })
+})
+```
+
+### 5. poolStore 测试增强
+
+**文件**: `test/stores/connectionPool.test.ts`
+**用例目标**: 15+ (新增 8)
+
+```typescript
+describe('Connection Pool Store', () => {
+ // 已有: 基本接口验证
+ // 新增:
+ it('应拒绝超过最大连接数的新连接')
+ it('LRU 淘汰应移除最久未使用的连接')
+ it('后台连接超过最大数应断开最旧')
+ it('活跃连接不应被 LRU 淘汰')
+ it('连接状态机转换应完整覆盖')
+ it('挂起超时 30 分钟应彻底断开')
+ it('保活心跳应重置空闲计时器')
+})
+```
+
+### 6. lifecycleStore 测试
+
+**文件**: `test/stores/lifecycleStore.test.ts`
+**用例目标**: 10+
+
+---
+
+## P1: IPC Handler 测试(第三批)
+
+### 7. SSH IPC 测试
+
+**文件**: `test/ipc/ssh.ipc.test.ts`
+**用例目标**: 8+
+
+```typescript
+describe('SSH IPC Handlers', () => {
+ it('ssh:connect 应调用 sshService.connect')
+ it('ssh:disconnect 应调用 sshService.disconnect')
+ it('ssh:create-shell 应调用 sshService.createShell')
+ it('ssh:shell-write 应调用 sshService.shellWrite')
+ it('ssh:shell-resize 应调用 sshService.shellResize')
+ it('ssh:forward-local 应调用 sshService.forwardLocal')
+ it('ssh:forward-remote 应调用 sshService.forwardRemote')
+ it('无效参数应返回错误')
+})
+```
+
+### 8. SFTP IPC 测试
+
+**文件**: `test/ipc/sftp.ipc.test.ts`
+**用例目标**: 8+
+
+### 9. Session IPC 测试
+
+**文件**: `test/ipc/session.ipc.test.ts`
+**用例目标**: 6+
+
+### 10. Settings IPC 测试
+
+**文件**: `test/ipc/settings.ipc.test.ts`
+**用例目标**: 4+
+
+### 11. 其他 IPC 测试
+
+**文件**: `test/ipc/{dialog,file,zmodem,app}.ipc.test.ts`
+**用例目标**: 每个文件 3-5+
+
+---
+
+## P2: UI 层测试(第四批)
+
+### 12. TerminalView 组件测试
+
+**文件**: `test/components/TerminalView.test.tsx`
+**用例目标**: 10+
+
+```typescript
+// Mock xterm
+vi.mock('@xterm/xterm', () => ({
+ Terminal: vi.fn().mockImplementation(() => ({
+ onData: vi.fn(), onResize: vi.fn(), open: vi.fn(),
+ write: vi.fn(), dispose: vi.fn(), cols: 80, rows: 24,
})),
}))
describe('TerminalView', () => {
- beforeEach(() => {
- vi.clearAllMocks()
- })
-
- it('should render terminal container', () => {
- render()
- expect(screen.getByText('连接成功!')).toBeDefined()
- })
-
- it('should show connecting status', () => {
- render()
- expect(screen.getByText('正在连接...')).toBeDefined()
- })
+ it('应渲染终端容器')
+ it('应显示连接中状态')
+ it('连接成功应初始化 XTerm')
+ it('连接失败应显示错误信息')
+ it('Shell 数据应写入终端')
+ it('终端输入应发送到 Shell')
+ it('窗口调整应 resize 终端')
+ it('组件卸载应释放资源')
})
```
-#### Sidebar.test.tsx
+### 13. useSFTP Hooks 测试
-```typescript
-import { describe, it, expect, vi, beforeEach } from 'vitest'
-import { render, screen, fireEvent } from '@testing-library/react'
-import Sidebar from '../../src/components/Sidebar'
+**文件**: `test/hooks/useSFTP.test.ts`
+**用例目标**: 15+
-describe('Sidebar', () => {
- beforeEach(() => {
- vi.clearAllMocks()
- window.electronAPI.sessionGetAll.mockResolvedValue({
- success: true,
- sessions: [],
- })
- })
+### 14. 其他组件测试
- it('should render quick connect button', () => {
- render()
- expect(screen.getByText('快速连接')).toBeDefined()
- })
-
- it('should call onQuickConnect when button clicked', () => {
- const onQuickConnect = vi.fn()
- render()
-
- fireEvent.click(screen.getByText('快速连接'))
- expect(onQuickConnect).toHaveBeenCalled()
- })
-
- it('should display sessions from API', async () => {
- window.electronAPI.sessionGetAll.mockResolvedValue({
- success: true,
- sessions: [
- { id: '1', name: 'Server 1', host: '192.168.1.1', port: 22 },
- ],
- })
-
- render()
-
- expect(await screen.findByText('Server 1')).toBeDefined()
- })
-})
-```
+- `test/components/Sidebar.test.tsx` — 5+
+- `test/components/SessionDialog.test.tsx` — 5+
+- `test/components/SFTPView.test.tsx` — 5+
---
-## 第三阶段:集成测试 (P1)
+## P3: E2E 集成测试(远期)
-### 3.1 IPC 通信测试
-
-```typescript
-// tests/integration/ipc.test.ts
-describe('IPC Communication', () => {
- describe('SSH Operations', () => {
- it('should connect and create shell', async () => {
- // Mock successful connection
- window.electronAPI.sshConnect.mockResolvedValue({
- success: true,
- connectionId: 'conn-1',
- })
- window.electronAPI.sshCreateShell.mockResolvedValue({
- success: true,
- shellId: 'shell-1',
- })
-
- // Simulate connection flow
- const config = { host: 'test', port: 22, username: 'user', password: 'pass' }
- const connResult = await window.electronAPI.sshConnect(config)
-
- expect(connResult.success).toBe(true)
- expect(connResult.connectionId).toBe('conn-1')
-
- const shellResult = await window.electronAPI.sshCreateShell('conn-1', { cols: 80, rows: 24 })
- expect(shellResult.success).toBe(true)
- })
- })
-
- describe('Session CRUD', () => {
- it('should create, read, update, delete session', async () => {
- // Create
- window.electronAPI.sessionCreate.mockResolvedValue({
- success: true,
- session: { id: 'sess-1', name: 'Test', host: 'localhost' },
- })
-
- const createResult = await window.electronAPI.sessionCreate({
- name: 'Test',
- host: 'localhost',
- port: 22,
- username: 'user',
- })
- expect(createResult.success).toBe(true)
-
- // Update
- window.electronAPI.sessionUpdate.mockResolvedValue({
- success: true,
- session: { id: 'sess-1', name: 'Updated', host: 'localhost' },
- })
-
- const updateResult = await window.electronAPI.sessionUpdate('sess-1', { name: 'Updated' })
- expect(updateResult.success).toBe(true)
- expect(updateResult.session.name).toBe('Updated')
-
- // Delete
- window.electronAPI.sessionDelete.mockResolvedValue({ success: true })
- const deleteResult = await window.electronAPI.sessionDelete('sess-1')
- expect(deleteResult.success).toBe(true)
- })
- })
-})
-```
-
-### 3.2 SFTP 集成测试
-
-```typescript
-// tests/integration/sftp.test.ts
-describe('SFTP Operations', () => {
- beforeEach(() => {
- window.electronAPI.sshConnect.mockResolvedValue({
- success: true,
- connectionId: 'conn-1',
- })
- window.electronAPI.sftpConnect.mockResolvedValue({
- success: true,
- sftpId: 'sftp-1',
- })
- })
-
- it('should connect to SFTP and list directory', async () => {
- window.electronAPI.sftpListDirectory.mockResolvedValue({
- success: true,
- files: [
- { filename: 'file1.txt', attrs: { isDirectory: () => false, size: 1024 } },
- { filename: 'dir1', attrs: { isDirectory: () => true, size: 0 } },
- ],
- })
-
- const sftpResult = await window.electronAPI.sftpConnect('conn-1')
- expect(sftpResult.success).toBe(true)
-
- const listResult = await window.electronAPI.sftpListDirectory('sftp-1', '/home/user')
- expect(listResult.success).toBe(true)
- expect(listResult.files).toHaveLength(2)
- })
-})
-```
-
----
-
-## 第四阶段:E2E 测试 (P2)
-
-### 4.1 Playwright 配置
+### Playwright 配置
```typescript
// playwright.config.ts
import { defineConfig } from '@playwright/test'
-
export default defineConfig({
- testDir: './tests/e2e',
+ testDir: './test/e2e',
timeout: 30000,
- use: {
- baseURL: 'http://localhost:5173',
- headless: true,
- },
- webServer: {
- command: 'npm run dev',
- port: 5173,
- reuseExistingServer: true,
- },
+ use: { baseURL: 'http://localhost:5173' },
})
```
-### 4.2 E2E 测试用例
+### E2E 用例
-```typescript
-// tests/e2e/connection.spec.ts
-import { test, expect } from '@playwright/test'
-
-test.describe('SSH Connection Flow', () => {
- test('should connect via quick connect dialog', async ({ page }) => {
- await page.goto('/')
-
- // Click quick connect
- await page.getByText('快速连接').click()
-
- // Fill form
- await page.getByPlaceholder('主机地址').fill('localhost')
- await page.getByPlaceholder('端 口').fill('22')
- await page.getByPlaceholder('用户名').fill('test')
-
- // Submit
- await page.getByText('连接').click()
-
- // Should show terminal
- await expect(page.locator('[data-testid="terminal"]')).toBeVisible()
- })
-
- test('should connect via sidebar session', async ({ page }) => {
- await page.goto('/')
-
- // Add a session first (via API mock in real test)
- // Click session in sidebar
- await page.getByText('测试服务器').click()
-
- // Should open terminal tab
- await expect(page.locator('[data-tab-title="测试服务器"]')).toBeVisible()
- })
-})
-
-test.describe('SFTP Flow', () => {
- test('should show session selection when no session provided', async ({ page }) => {
- await page.goto('/')
-
- // Open SFTP
- await page.getByText('SFTP 传输').click()
-
- // Click connect
- await page.getByText('选择服务器').click()
-
- // Should show session list
- await expect(page.getByText('选择要连接的服务器')).toBeVisible()
- })
-})
-```
+- 快速连接 → SSH 终端出现
+- 侧边栏会话 → 点击 → 终端连接
+- SFTP → 选择服务器 → 浏览目录
+- 标签页 → 创建 → 切换 → 关闭
---
@@ -492,63 +366,37 @@ test.describe('SFTP Flow', () => {
### 命令
```bash
-# 运行所有测试
-npm test
-
-# 带覆盖率
-npm test -- --coverage
-
-# 监视模式
-npm test -- --watch
-
-# E2E 测试
-npm run test:e2e
-
-# 带 UI 的 Vitest
-npm run test:ui
+npm test # 运行所有测试
+npm test -- --coverage # 带覆盖率报告
+npm test -- test/services/ # 只跑 services 测试
+npm test -- --reporter=verbose # 详细输出
+npm test -- --watch # 监听模式
```
-### CI 配置
+### CI 集成(规划)
```yaml
# .github/workflows/test.yml
-name: Test
-on: [push, pull_request]
-jobs:
- test:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: '20'
- - run: npm ci
- - run: npm run lint
- - run: npm test -- --coverage
- - uses: codecov/codecov-action@v3
+- name: Test
+ run: npm test -- --coverage
+- name: Coverage Check
+ run: |
+ if [ $(npm test -- --coverage --reporter=json 2>/dev/null | jq '.total.lines.pct') -lt 50 ]; then
+ echo "Coverage below 50%"
+ exit 1
+ fi
```
---
-## 覆盖率目标
+## 覆盖率追踪
-| 版本 | 单元测试 | 集成测试 | E2E |
-|------|----------|----------|-----|
-| v1.0.0 | 20% | 10% | 5% |
-| v1.1.0 | 40% | 20% | 10% |
-| v1.2.0 | 60% | 30% | 15% |
-
----
-
-## 测试优先级矩阵
-
-| 功能模块 | 单元测试 | 集成测试 | E2E | 优先级 |
-|----------|----------|----------|-----|--------|
-| tabStore | ✅ | - | - | P0 |
-| connectionStore | ✅ | ✅ | - | P0 |
-| TerminalView | ✅ | ✅ | ✅ | P0 |
-| SFTPView | ✅ | ✅ | ✅ | P1 |
-| Sidebar | ✅ | ✅ | ✅ | P1 |
-| SessionDialog | ✅ | ✅ | - | P1 |
-| ssh-service | - | ✅ | - | P0 |
-| database-service | - | ✅ | - | P1 |
+| 版本 | 总覆盖率 | 核心模块 | 用例数 | 日期 |
+|------|----------|----------|--------|------|
+| v1.0.0 | ~10% | 0% | 34 | 2026-04-06 |
+| v1.1.0 | ~12% | 0% | 34 | — |
+| v1.2.0 | ~15% | 0% | 40 | — |
+| v1.3.0-batch1 | ~25% | 60% | 69 | — |
+| v1.3.0-batch2 | ~35% | 60% | 104 | — |
+| v1.3.0-batch3 | ~45% | 70% | 143 | — |
+| v1.3.0-final | **≥50%** | **≥80%** | **150+** | — |