本清单把“代码/构建检查”与“真实双机功能验收”分开。任何未执行项都必须写“未测”,不能用 CI 成功推断为通过。
- 主端:macOS 14+;至少一台 Apple Silicon Mac。若声明 Intel 支持,还需一台 Intel Mac 单独通过。
- 子端:Windows 10 22H2 64 位和 Windows 11 64 位应分别验收;如果只测其中一个,只能声明该系统已测。
- MVP:一主一子、单路视频、可信 IPv4 LAN、无认证。
- 明确排除:音频、键鼠/触控回传、HDR、多子端、IPv6、公网/NAT、App Store。
日期:
提交 SHA / 版本:
Mac 型号 / CPU / macOS build:
Windows 型号 / CPU / GPU / Windows build:
网络(有线/Wi-Fi、AP/VLAN):
主端产物 SHA-256:
子端产物 SHA-256:
验收人:
结论:通过 / 有条件通过 / 不通过
已知问题链接:
每个失败都保留复现步骤、脱敏日志、截图/短视频和 issue 链接。不要在证据中暴露真实敏感屏幕、设备名、IP、UUID、SDP 或 ICE。
| ID | 检查 | 命令/方法 | 通过标准 | 状态 |
|---|---|---|---|---|
| A01 | 锁定安装 | npm ci |
无锁文件漂移,退出码 0 | 执行时填写 |
| A02 | JS/MJS 语法 | npm test 的 pretest |
所有源文件语法通过 | 执行时填写 |
| A03 | 单元测试 | npm test |
0 失败、0 意外跳过 | 执行时填写 |
| A04 | Mac helper 编译 | Mac 上 npm run build:native |
-Werror 下成功且二进制存在 |
执行时填写 |
| A05 | 私有 API 探测 | lanextend-vdisplay --probe |
目标 Mac 返回 available: true |
必须真机填写 |
| A06 | Mac 打包 | npm run dist:mac |
DMG/ZIP 均生成;app 与 helper 经 lipo 确认含 arm64/x86_64 |
执行时填写 |
| A07 | Windows 打包 | Windows 上 npm run dist:win |
portable EXE/ZIP 均生成 | 执行时填写 |
| A08 | CI | build.yml 两个 job |
同一提交 Mac/Windows job 均绿且 artifacts 可下载 | 执行时填写 |
| A09 | 许可证 | 人工检查 | LICENSE、第三方声明、锁文件与打包依赖一致 | 执行时填写 |
| A10 | 文档范围 | 人工检查 | 明确 14+、Win10/11、MVP 限制、无认证和无签名 | 执行时填写 |
| A11 | 更新检查 | tests/updates.test.js + GUI |
语义版本比较正确,只接受本仓库 HTTPS Release 链接,失败可重试 | 执行时填写 |
- I01 Mac 从候选 DMG/ZIP 启动;记录 Gatekeeper 行为,未把未签名产物描述为正式发布。
- I02 Windows portable EXE/ZIP 启动;记录 SmartScreen 和 Defender 防火墙行为。
- I03 Windows 仅在“专用网络”放行,公用网络未放行。
- I04 主端/子端角色自动正确;标题和页面无角色混淆。
- I05 首次设置生成;重启后子端 UUID 保持,名称/端口保持。
- I06 单实例行为正确;第二次启动聚焦现有窗口或安全退出。
- V01 选中子端并点击“扩展到 …”后,主端先收到/核对
welcome,再自动创建一块默认显示器;helper 8 秒超时边界内报告成功,系统“显示器”中可见。页面不存在误导性的独立创建按钮。 - V02 显示器可在系统排列中拖到主屏四周,窗口能移入该桌面。
- V03 1920×1080、30 FPS、非 HiDPI 的逻辑尺寸与物理 framebuffer 均为 1920×1080。
- V04 至少验证一个 HiDPI 配置;输入保持逻辑宽高,物理 framebuffer 宽高各 2×(如 1920×1080 → 3840×2160),画面未裁切。
- V05 非法宽高/FPS 在 GUI/主进程被拒绝,不启动 helper。
- V06 销毁后系统显示器消失,原窗口由 macOS 正常收回。
- V07 主端正常退出后 helper 不残留、显示器消失。
- V08 helper 异常退出后 GUI 状态更新,不把显示器继续显示为运行中。
- V09 屏幕录制权限拒绝/撤销时有明确提示,不绕过系统权限,不崩溃。
- V10 macOS 更新目标版本上重新运行 probe、创建、捕获和释放全流程。
- D01 先开 Windows 后,Mac 在 5 秒左右显示在线子端,名称/IP/端口正确。
- D02 关闭子端,约 6–8 秒后设备变离线而不是从记忆列表消失。
- D03 重开子端后同一 UUID 合并为在线项,不生成重复记录。
- D04 广播被防火墙阻止时,手动私有 IPv4 + 端口可以连接。
- D05 公网 IP、IPv6、主机名、非法端口被拒绝。
- D06
welcome后手动地址临时 ID 被真实子端 UUID 替换;成功连接后记录lastConnected和最近设备,完全重启主端后仍存在。 - D07 “忘记设备”后记录消失,最近设备引用被清理。
- D08 超过 32 个合法设备时按时间保留最近 32 个,不无限增长。
- D09 子端改名/改端口后服务重启并广播新值,主端随后更新。
- D10 两个子端 UUID 相同的异常场景被记录为已知风险;克隆系统部署有重置步骤。
- R01 默认“创建扩展屏”按 helper 返回的 display ID/名称自动匹配正确虚拟屏;兼容模式手选已有屏时先用无敏感测试图确认没有误捕主屏。
- R02 主端主动连接;顺序为 WebSocket →
welcome真实 UUID →hello→ 自动创建/捕获(或兼容源)→ offer/answer/ICE → 已连接。 - R03 Windows 显示 Mac 虚拟桌面,色彩、比例、方向正确,无明显裁切/拉伸。
- R04 把窗口在主屏与扩展屏之间拖动,Windows 只显示扩展屏内容。
- R05 子端顶部按钮、画面悬浮按钮和 Esc 均可退出全屏;多显示器 Windows 上位于期望屏幕。
- R06 主端主动断开后视频停止、双方状态复位、Windows 恢复显示休眠策略。
- R07 子端主动断开后主端感知并可重新连接。
- R08 网络/异常断线按约 1.6/3.2/6.4/12 秒指数退避(12 秒封顶)自动重连,用户可取消;主动断开、显式
disconnect、WebSocket 1000/1008 不重连。 - R09 连续重连 10 次,无残留 WebSocket/peer/helper 和明显资源递增。
- R10 已连接时第二台 Mac 被子端以单会话策略拒绝,不影响现有会话。
- R11 两端使用不同协议版本时明确失败,不进入假连接状态。
- R12 让 Mac/Windows 分别睡眠/唤醒,记录实际行为;若不能恢复,UI 至少允许干净断开重连。
- R13 子端视频出现后底部信息条默认隐藏;画面内移动鼠标/触摸/键盘聚焦后显示,无操作约 2.2 秒后隐藏;悬停按钮时不会在操作中消失。
本 MVP 没有承诺固定延迟/FPS;以下是建议验收基线,不应在未测时写入产品宣传。
| ID | 优先级 | 场景 | 建议通过标准 | 结果 |
|---|---|---|---|---|
| P01 | P0 | 1080p30 / 8 Mbps / 有线,30 分钟 | 无崩溃/永久黑屏;交互可用;会话能正常结束 | 待测 |
| P02 | P0 | 1080p30 / 8 Mbps / 常用 Wi‑Fi,30 分钟 | 短暂波动可恢复,无持续断开 | 待测 |
| P03 | P0 | CPU/GPU/内存观察 | 无持续无界增长;记录双方峰值和稳态 | 待测 |
| P04 | P1 | 1080p60 | 仅在目标硬件实测后列为支持 | 待测 |
| P05 | P1 | HiDPI/高分辨率 | 无裁切,资源与带宽可接受 | 待测 |
| P06 | P1 | 1%/3% 人工丢包 | 会话可恢复或给出明确断开,不假死 | 待测 |
| P07 | P1 | 连续 8 小时 | 无崩溃、helper 泄漏或不可恢复黑屏 | 待测 |
如果要声明延迟数值,必须说明测量方法(相机/时间码)、网络、分辨率、帧率、编码路径、样本数和 P50/P95;主观“很低”不能作为证据。
- S01 README/GUI 明确“仅可信内网、无认证”,没有“安全连接/受信设备”等误导文案。
- S02 Windows 信令端口未映射公网,防火墙不对公用网络开放。
- S03 伪造/超大/无效发现包不会导致主端崩溃或写入非法公网设备。
- S04 超 256 KiB、未知类型、版本错误或畸形信令被拒绝并关闭。
- S05 任意 HTTPS 之外页面不能在 Electron 内导航,渲染层没有 Node 集成。
- S06 配置文件不保存屏幕帧、SDP/ICE、密码或长期密钥;日志默认不输出敏感信令。
- S07 屏幕权限拒绝时失败关闭,不尝试 TCC 绕过;应用不申请辅助功能/麦克风。
- S08 明确记忆设备可伪造,不把 UUID/名称当认证。
- S09 未签名 artifacts 明确标记开发验收用途,没有建议全局关闭 Gatekeeper/SmartScreen。
- S10 第三方 GPL/AGPL 方案未复制进 MIT 实现;引用与许可证边界有记录。
以下项目若意外“看似可用”也不应纳入 v0.2.0 支持声明:
- 音频播放/转发;
- Windows 到 Mac 的键盘、鼠标、触控、剪贴板或文件回传;
- HDR、广色域、色彩校准保证;
- 一台 Mac 同时连接多个 Windows 子端或创建多块受管扩展屏;
- IPv6、DNS 名称、跨公网、NAT、TURN、云中继;
- 身份认证、配对、授权、受信设备安全列表;
- Mac App Store、后台下载/静默自动安装、正式签名/公证;
- 无人值守服务和企业集中管理。
- A01–A10 有真实记录;
- P0 功能失败有明确已知问题,不把未测能力写成已支持;
- 两端 artifacts 能从同一提交构建;
- 安全边界、私有 API 和签名状态在 README/GUI/发布说明一致。
- 所有 P0 双机项通过;
- 至少 Windows 10、Windows 11 和目标 Mac CPU/OS 矩阵有记录;
- 完成 30 分钟稳定性和 10 次重连;
- 配置受控 VLAN/防火墙;
- 内部分发包已签名并有哈希/回滚流程。
- helper 无法稳定清理或捕获源可能默默切到主屏;
- 无认证限制未披露,或端口计划暴露到不受控网络;
- 双机视频未测却宣称“完整可用”;
- app 或 helper 缺少任一架构 slice,却被标记为 Universal;
- 未完成许可证审查、签名来源不明或构建不可追溯。