PROJECT_EVALUATION.md - 项目评估和质量指标
本文档定义 OpsXShell 的质量标准、评估指标和改进目标。
版本历史
| 日期 |
版本 |
评分 |
主要变更 |
| 2026-04-04 |
v0.1.0 |
56/100 |
初始骨架 |
| 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 维度独立审计重新评估,结果显著低于历史记录。这是正常的——自评往往偏高,独立审计才能暴露真实问题。
v1.0.0 独立审计评估 (2026-04-18)
整体评分
| 维度 |
分数 |
权重 |
加权分 |
说明 |
| 功能完成度 |
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 脚本跨平台兼容性差 |
综合评分: 58/100 — 功能原型阶段,距生产可用尚有差距
评分对比
代码统计
总量
| 目录 |
文件数 |
代码行数 |
占比 |
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% |
需重点关注的文件
| 文件 |
行数 |
问题 |
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 耦合 |
SWOT 分析
Strengths (优势)
- 加密实现专业: AES-256-GCM + PBKDF2(100K迭代) + 随机 Salt/IV,业界最佳实践
- IPC 架构清晰: 8 个模块化 IPC Handler,通道常量统一管理
- 连接管理设计: 状态机 + 连接池 + LRU 淘汰 + 保活,架构先进
- 错误处理体系: 统一错误码 + 错误推断 + ErrorBoundary + 高阶包装函数
- 共享类型:
shared/types/ 主进程/渲染进程共用类型
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"
Opportunities (机会)
- Electron 升级: v33+ 性能提升 30%+,内存占用更低
- Zustand v5: 细粒度订阅,减少不必要的重渲染
- XTerm.js 插件生态: Image addon、Web Links addon 可增强终端功能
- 打包优化: electron-builder + asar 可显著减小安装包体积
Threats (威胁)
- 安全风险: 密码可能通过 IPC 明文传输;
sandbox: false 降低安全性
- 竞品压力: Electerm、Tabby、Termius 等成熟竞品功能更完善
- 跨平台兼容:
dev 脚本用 & 后台运行,Windows 不可用
- 依赖锁定: ssh2、socksv5 版本锁定,存在已知漏洞风险
关键问题清单
🔴 Critical — 必须修复
| ID |
问题 |
位置 |
影响 |
| 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 |
生产环境显示假文件 |
🟡 Warning — 建议修复
| 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 |
依赖评估
| 依赖 |
当前 |
最新 |
状态 |
风险 |
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 |
🟢 稳定 |
— |
测试评估
现状
| 测试文件 |
用例数 |
覆盖模块 |
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 |
✅ |
| 内存占用(10标签) |
~200MB |
<150MB |
❌ |
| 标签切换延迟 |
<50ms |
<100ms |
✅ |
| 包体积 |
~120MB |
<100MB |
❌ |
优化方向与目标
v1.1.0 — 代码质量清理 (预计 1 周)
目标: 清除生产代码中的调试残留,提升代码质量评分至 70+
| 任务 |
优先级 |
影响文件 |
预计工时 |
| 移除所有 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 |
延迟加载非核心模块 |
里程碑总览
成功指标
| 指标 |
v1.0 当前 |
v1.5 目标 |
| 综合评分 |
58/100 |
80+/100 |
| 测试覆盖率 |
~10% |
≥50% |
| 代码质量(零console.log) |
50+ 处 |
0 处 |
| 单文件最大行数 |
685 |
≤300 |
| Electron 版本 |
v28 |
v33+ |
| 安全评分 |
55 |
75+ |
| 包体积 |
~120MB |
<100MB |