知序 / 研究笔记
Engineering proposal · macOS first

把 iPhone 接进
桌面工作台。

从开源虚拟机到一个可安装、可控制、可诊断的设备面板。先厘清系统边界,再把重复操作收进产品。

2026.09.24 · 方案 v1.0 · 源码快照 3f7011406722

目标架构设计示意 · 非实机画面
Desktop · 设备面板安装应用 / 画面 / 操作 / 诊断
↓
本地 Device Service生命周期 · 版本 · 权限 · 故障归因
↓
Simulator Adapter客户端开发主线
VPhone Adapter研究设备 / IPA 验证

同一面板,两种设备后端;根据安装包类型和宿主条件选择,不静默切换。

先看结论

可以做。上游当前设计将常规运行依赖收进应用,但普通 Mac 上的首次运行仍有恢复模式与系统授权门槛。建议以统一设备面板交付能力:Simulator 承接常规开发,vphone 在已准备好的研究设备上验证 IPA;若要求普通用户零宿主操作,采用已配置的远端物理 Mac,而非承诺本地脚本包办。

真正要交付的是设备工作流。

需求可以归纳为:开发者在桌面工作台新增「设备」面板,就能启动一台 iPhone、安装自己的应用、看到画面,并把点击、输入、截图等能力交给自动化工具。安装环境、定位失败、维护版本,应该由工作台承担。

本方案把提供的讨论截图作为需求背景;其中关于内存、API 和 App 兼容性的判断均重新核验。公开页面采用概括描述,不附内部聊天截图、人员信息或业务安装包。

路线适用场景主要代价本方案决策
Xcode Simulator有源码、能产出 Simulator .app 的日常客户端开发Xcode 与 Runtime 体积;真机 IPA 不能直接作为模拟器构建运行产品默认候选;由 simctl 管生命周期,idb/原生桥接补充交互
本地 vphone研究型 iOS 环境,验证受控开发 IPA 与自动化能力Apple Silicon、研究虚拟机授权、固件与管理员操作首轮技术 PoC;在明确具备条件的机器启用
远端物理 Mac + vphone用户机器不能改系统设置,仍需要 vphone 能力设备池、鉴权、流媒体、隔离与运营成本严格零本地配置场景的候选;不是当前已交付服务
真机 / 设备云硬件、签名、风控与真实环境一致性验证配对、设备占用、账户与供应商集成业务验收补充,不将虚拟机结论直接外推真机

Simulator 交互扩展参考 idb / FBSimulatorControl;Runtime 自动下载参考 Apple 官方文档。并非“Xcode 没有可控 API”,而是需要组合生命周期、输入与画面能力。

建议:Simulator 优先

构建 Simulator .app;自动检查 Xcode、下载 Runtime、创建设备并安装。缺少 Xcode 或尚未授权时仍存在宿主前置条件。

这是方案选择器,不会检测电脑或执行安装。

vphone 是研究虚拟机,不是 Simulator 外壳。

它基于 Apple Virtualization.framework 与 PCC 研究虚拟机基础设施,组合 iPhone 与 cloudOS 固件,修改启动及系统组件,在虚拟机中部署 vphoned。由宿主 CLI 编排,独立的 vphone-vm 负责实际运行。[1]

版本必须固定。调研初次读取未固定版本的网页,返回了与当前快照不同的说明:Homebrew 依赖、-V jb、SSH/VNC。随后下载的固定源码及其中的中英文文档呈现了新行为。该网页结果未绑定历史 commit,差异原因未确认;本文以固定 commit 为准,未固定网页与历史截图仅用于对照。

事项未固定网页 / 截图印象固定源码的实际行为
依赖安装安装大量 brew 包、Python venv上游文档声明分发 .app 运行时不要求 brew / Python / Xcode,源码也已内置相关组件;干净机分发验收仍待完成。源码构建需完整 Xcode 和 iPhoneOS SDK
固件变体less / regular / dev / jb / exp,-V jb当前 CLI 仅 JB 主线,create 没有 variant 选项;非交互运行要提供两份固件来源
远程连接默认 SSH 22222、VNC 5901当前不默认安装 SSH/VNC/包管理器;使用 guest HTTP/WS、宿主 Unix socket
create 成功设备已经持续运行首启验证 vphoned ping 后停止验证实例;必须再 launch 才进入持续使用
进程被 Killed直接判定内存耗尽也可能是 AMFI 拒绝带私有 entitlement 的进程;先取证,不能仅凭信号 9 定性

创建链路,逐层看成本

宿主预检→固件准备→JB 补丁→DFU 恢复→CFW 安装→首启 ping→另行 launch

固件准备包含解包与 GPU 驱动准备;恢复需要联网获取 Apple restore ticket;CFW 通过宿主挂载磁盘安装,涉及管理员权限。默认创建配置为 8 vCPU、8192 MiB 内存、64 GB 虚拟磁盘。这是源码默认值,不是宿主只要空闲 64 GB 就够的容量结论。解包、缓存、临时磁盘都要计入。64 GB 是稀疏虚拟磁盘的逻辑容量;当前 create CLI 只暴露 disk-size,CPU/内存默认值不能直接通过 create 参数修改。[2]

上游记录两组固件完成过到锁屏及 vphoned ping 的验证;它们是上游证据,不是本次在当前机器上运行的结果,也不代表业务 App 已兼容。[3]

把安装做进产品,而不是写一页前置条件。

目标体验是「打开设备面板 → 自动检查 → 自动准备可完成的部分 → 设备就绪」。主路径不要求用户打开终端、安装 Homebrew、配置 PATH 或逐个复制命令。下面是产品化设计;下载区提供的是开发验证包,两者完成度分别标记。

  1. 发布端先做重活

    CI 固定源码及 Package.resolved,构建完整 runtime .app;记录散列、签名、依赖清单、兼容矩阵。每版在干净物理 Mac 上验证。私有 entitlement 可否正常分发、签名与公证必须实测,不把 ad-hoc 签名等同于常规公证可分发。

  2. 桌面启动后探测,不先下载

    检查 CPU、系统、是否嵌套虚拟化、磁盘容量、当前资源占用与 host preflight。preflight 检查嵌套环境、伴随进程及 entitlement,并探测其 --help 是否被拒绝;不验证 Recovery 配置、固件或真正的 PV=3 建机。通过后仍要验证真实 VM 启动。

  3. 按需获取内置运行包

    默认复用自有兼容运行包,缺失时由安装管理器下载固定版本到暂存目录,校验 SHA-256 和签名,再原子切换版本目录。所有数据放在用户 Application Support 中,不改 shell 配置。

  4. 固件目录替用户做选择

    产品维护已验证的 iPhone/cloudOS 配对清单及摘要;优先使用合法可用的本地缓存,否则后台从明确来源下载。UI 只显示大小、进度和失败原因。离线包只承诺可缓存素材,在线 restore ticket 仍可能必需。

  5. 单实例创建,失败保留证据

    对每台设备加任务锁,串行执行昂贵阶段;记录阶段输入散列、产物与日志。下载可续传,阶段恢复须校验前序产物。上游 create 对同名目录会报错,不能把“重跑 create”称为自动续装。

  6. 验证后交接给面板

    create 完成后单独 launch;等待 health、host ping 与首帧,再进入 Ready。网络恢复后只重试可幂等请求;IPA 安装等变更操作先核实结果,避免重复执行。

哪些真的能自动完成?

步骤自动化策略用户侧边界
brew / Python / 编译工具运行包由产品预构建;不转嫁给最终用户开发调试包单独需要 Python;源码构建需要完整 Xcode
下载、缓存、解包、建机任务队列、散列校验、进度事件、可恢复检查点磁盘不足或外部服务不可达时展示具体阻断
CFW 管理员权限PoC 用上游 --root-popup;生产设计受限权限 helper系统认证仍可能需要确认;不收集或保存 sudo 密码
PV=3 / SIP / AMFI只检测并报告,不偷偷调整恢复模式设置无法由普通桌面脚本完成;白名单与 build 签名相关,重建后需重新处理
应用安装与控制上传→安装→查询→启动→前台及截图确认,统一一个操作业务登录、硬件依赖、包兼容性不能承诺自动解决

零人工的可行定义:在已准备的受管研究 Mac 上,后续设备创建与使用尽量自动化;在普通未配置 Mac 上,vphone 当前不能满足“用户一次操作也没有”。上游两种宿主方案都涉及 Recovery 配置。严格要求零宿主变更时,应选已具备条件的 Simulator 环境,或由运维预配置的远端物理 Mac 服务。[4]

状态机与更新策略

Unknown → Checking → RuntimeReady → FirmwareReady
  → Creating → Verifying → Stopped → Starting → Ready

任意阶段 → Blocked(明确条件)/ Failed(可诊断)
Ready → Stopping → Stopped
更新:新版本预检 → 新设备验证 → 切换;旧运行包与旧设备保留

错误码区分 HOST_POLICY_BLOCKED、RESOURCE_LOW、DOWNLOAD_FAILED、RESTORE_FAILED、GUEST_NOT_READY、APP_INCOMPATIBLE。日志默认本地脱敏保存,导出前排除账户信息、签名证书与应用内容。卸载仅移除本产品管理的 runtime;删除设备数据应作为独立操作。

面板管交互,服务管设备。

未取得实际 Desktop 源码,本方案按 Electron / WebView 工作台假设设计。实现前确认主进程与渲染进程边界,保留现有 UI 框架;不要为了引入虚拟机更换桌面架构。

Renderer / Device Panel
    │ 受限 IPC:list / create / launch / stop / install / input
Desktop Main Process
    │ 参数校验、任务 ID、取消、授权与目录边界
Device Service(本地进程;普通用户权限)
    ├── Runtime Manager / Firmware Cache / Job Store
    ├── Simulator Adapter → simctl + idb 或原生桥
    └── VPhone Adapter
          ├── vphone-cli:生命周期、固件、创建
          ├── HTTP / WS → VSOCK 1339 → vphoned
          └── Unix socket → 截图、tap、swipe、硬件键

直接复用的接口

用途上游现有能力接入注意
健康与能力GET /v1/health、GET /openapi.json启动后校验 runtime / daemon 兼容,接口缺失显式降级
应用与文件/v1/apps、/v1/apps/install、/v1/files/content本机路径与 guest 路径不同,安装需先上传
事件与输入/v1/events WebSocket、input.touch 等 RPC用请求 ID 关联响应;触摸发送 down / move / up;标准化坐标需映射方向与留白
截图与硬件键<bundle>/vphone.sock,JSON 行协议像素坐标;默认响应是缩小灰度 JPEG,不能当高保真录屏

HTTP/WS 转发通过 vm launch --api-listen 127.0.0.1:8765 显式启用。上游 API 当前没有认证,所以只能由受控本地服务访问;生产应优先直接封装 VSOCK/IPC,若必须 TCP,应增加代理鉴权、来源验证与绑定地址限制。单加一个代理 token 不会保护仍可被其他本地进程直连的裸端口。渲染器不暴露通用 shell 或任意 icli.execute。[5]

画面嵌入分两步,避免把截图说成视频

PoC:保持上游原生 VM 窗口,面板先提供低频截图预览和操作回执;需要彩色细节时向 Unix socket 发送带受控主机路径的 {"t":"screenshot","path":"/tmp/shot.png"},得到全尺寸截图文件。省略 path 只返回缩小灰度图,不落全尺寸文件。这可验证坐标、任务链与故障处理,不承诺流畅视频。

产品版:扩展宿主帧生产器,将图像通过受控共享内存或编码流送给面板。加入最新帧优先、背压、失焦降帧、断流重连与旋转映射;交互帧率与延迟作为实测指标。上游有本地 .mov 录屏实现,但未发现现成的面板视频流 API。原生 NSView 的跨进程嵌入另做小实验,不将拖入窗口当成稳定方案。[6]

面板只展示用户关心的状态

上方是设备选择与启动/停止;中央是设备画面;下方提供安装应用、Home、截图、诊断。首次安装显示阶段、已下载大小和可解释的阻断原因。默认隐藏固件内部术语;错误详情和版本记录留在“诊断”中。关闭面板是否保留设备运行由明确的会话策略决定,不能丢下不可见后台虚拟机。

能安装 IPA,不代表业务已经可用。

vphone 的应用安装不是 simctl install。源码会在 guest 中解包、重签并注册应用;apps.install 接收的是 guest 文件路径。Desktop 的安装按钮需要封装完整流程。[7]

  1. 检查安装包:识别 .app / .ipa、目标平台与架构、bundle ID、大小、来源和解包路径;Simulator 构建交给 Simulator,设备构建进入 vphone 兼容验证。
  2. 上传:流式写入 guest 临时目录;记录文件摘要。不要将宿主 /Users/…/app.ipa 直接填进 guest install 请求。
  3. 安装:调用 apps.install 并保留返回值;成功后查询安装列表,验证 bundle ID 和版本,再清理该任务的临时文件。
  4. 启动:调用 apps.launch,核查前台 bundle ID、进程与截图;如果立即退出,采集 crash 信息,标为启动失败而非安装成功。
  5. 业务验收:验证测试账号登录、首页、网络和一条核心链路。安装、进程存活、业务可用分别记录。

目标业务 App 目前的结论:待验证。本次没有目标包、签名配置或测试账户,不能确认可运行。商店下载包的加密、签名依赖、Keychain / 推送 / 完整性校验及虚拟环境检测均可能影响结果。首轮使用团队可控的开发 IPA,随后单独验证目标 App。

开源仓库为 MIT 许可;这不等于 Apple 固件、业务包、账户或修改宿主安全设置自动获得组织许可。软件分发、固件来源与研究机准入需要由项目责任方确认。这里没有作出“已符合企业安全规定”的结论。[8]

先找证据,再解释 Killed。

截图能证明进程被终止,不能证明 OOM。退出码 137 或 SIGKILL 只说明进程被信号 9 结束;AMFI、内存压力、主动结束或其他系统策略均需要相应证据。也没有依据把 JB 称作“更轻量的版本”。

现象检查应给出的结论与动作
窗口尚未出现就终止先运行 host preflight,结合 amfid / code signing 日志和准确时间、PID有拒绝证据才归为 AMFI;近期重建需检查 cdhash。单纯释放内存未必有用
解包或建机阶段中断可用磁盘、vm_stat、memory_pressure、进程峰值、memorystatus 日志有同一进程内存终止记录才归为 OOM;限并发、减少构建 jobs,并调整容量计划
恢复阶段失败网络、ticket 请求、固件配对、DFU 与 restore 日志归到对应阶段;先校验产物,不能无限重复整条流水线
设备启动但无法控制daemon 版本、health、socket ping、启动日志区分画面可见与服务 Ready;旧 daemon 不兼容时应重建匹配设备
应用安装后闪退bundle、签名/加密状态、crash log、前台进程报告包兼容或运行问题;不能把每次闪退都归因于虚拟机内存

附带脚本的 diagnose 读取本地日志线索,不自动修改系统设置,也不因关键词出现而确认根因。host preflight 的失败也不全是 AMFI:二进制缺失、版本不匹配等仍要保留原始错误。[9]

一个可下载、可审查的调试入口。

交付的是源码锁定的开发 PoC:把预检、准备、创建、启动、API 检查和诊断收在同一个入口。它不是已经签名分发的 Desktop 插件,也不包含 Apple 固件、业务 IPA 或预先修改好的系统镜像。

LOCAL PoC · macOS

vphone-local-kit

Python 标准库控制器 + Shell 入口 + 使用说明 + mock 验证。支持 dry-run,不自动变更 SIP / AMFI,不存储管理员密码。

以压缩包内 README 的命令和参数为准。源码绑定 commit,不使用漂移的 main。下载校验见 SHA256SUMS.txt。

脚本与命令清单

文件 / 命令已实现内容
vphone-localmacOS Shell 入口,调用 Python 3.9+
vphone_local.py标准库控制器:参数数组调用、本地数据隔离、超时及失败日志
doctor读取系统、架构、磁盘、内存、SDK 与嵌套环境;按需调用上游 preflight
bootstrap显式执行时获取固定源码并构建;也可复用已有 CLI
create / launch / stop本地固件建机、系统认证窗口、前台启动与停止;显式 execute 才执行
health / screenshot / touchloopback HTTP 健康检查;Unix socket 截图与像素坐标点击
diagnose从日志提取候选线索;不把 Killed 直接归因为 OOM
tests/test_vphone_local.pymock 回归:协议、预检、认证参数、版本约束和错误归因

尚未实现:可分发 runtime 下载管理、固件清单自动选择/下载、IPA 安装封装、Desktop 面板、视频流、任务断点恢复。这些属于前文产品设计。复用外部二进制时需另核版本;commit 锁定用于源码构建路径。

展开:本地开发调试命令
./vphone-local doctor
./vphone-local bootstrap --fetch-source --dry-run
# 需要完整 Xcode + iOS SDK;获取固定源码并构建
./vphone-local bootstrap --fetch-source --execute
VP="$PWD/upstream/.build/vphone-cli.app/Contents/MacOS/vphone-cli"
./vphone-local --cli "$VP" doctor --preflight
./vphone-local --cli "$VP" create devphone \
  --iphone-source /path/to/iPhone_Restore.ipsw \
  --cloudos-source /path/to/cloudOS.ipsw --execute
./vphone-local --cli "$VP" launch devphone --execute
# launch 持续占用前台,下面由并行调试进程调用
./vphone-local health
./vphone-local screenshot devphone --output /tmp/devphone.png
./vphone-local touch devphone 645 1398
./vphone-local --cli "$VP" stop devphone --execute

上游等价命令:解释实际做了什么

供开发审查;产品用户不需要输入这些命令
# 在完整 Xcode + iPhoneOS SDK 的构建机上构建固定快照
# 源码实际目录为 Scripts,注意 macOS 大小写敏感卷
zsh Scripts/build.sh

# 以下 VP 指向构建或分发包中的 CLI;数据目录由包装器隔离
VP="/path/to/vphone-cli.app/Contents/MacOS/vphone-cli"
"$VP" host preflight

# 固件来源由产品清单提供;这里为可读的本地占位路径
"$VP" vm create devphone \
  --iphone-source /path/to/iPhone_Restore.ipsw \
  --cloudos-source /path/to/cloudOS.ipsw \
  --root-popup

# create 验证后会停止,必须再启动
"$VP" vm launch devphone --api-listen 127.0.0.1:8765
# launch 是前台持续运行;以下为并行诊断端执行的等价请求
curl --fail http://127.0.0.1:8765/v1/health
curl --fail http://127.0.0.1:8765/openapi.json
"$VP" vm stop devphone

本地脚本使用 Python 是为了让开发者直接审查和调试;最终产品使用已内置的桌面运行时或编译后的原生服务,无需用户安装 Python。未将 Python 声称为 macOS 默认可用,也未以自动安装 brew 作为主解决方案。

本次验证边界

已通过 9 项 mock 回归检查,并完成页面桌面/手机、深浅色及交互检查。查看验证记录。

已核对固定源码及宿主环境,脚本验证记录随包提供。当前宿主只有 Command Line Tools,没有完整 Xcode;本次未构建上游 .app、未修改 SIP/AMFI、未下载固件、未创建真实 iOS VM,也未验证目标业务 App。

每个阶段都有可判断的完成条件。

阶段交付完成证据
P0 / 技术可行性固定版本脚本、1 台研究 Mac、受控开发 IPA预检→create→launch→health→首帧→安装→启动,保留版本与日志;三次独立运行复核
P1 / 面板接入设备服务、任务状态、截图/输入、安装进度可从面板完成一条完整链路;坐标正确、失败可诊断、取消后无遗留进程
P2 / 安装产品化签名 runtime、固件清单、缓存、受限权限 helper干净已准入宿主安装,无 brew / 终端步骤;中断、磁盘不足、版本回滚演练通过
P3 / 体验与扩展低延迟画面、Simulator adapter;按需远端设备画面/输入延迟、资源占用、断连与隔离实测;不以功能存在代替性能验收

建议两周完成 P0/P1 的小范围原型:设备服务与安装链路、面板与画面分别推进;这是在研究 Mac、开发 IPA 与桌面仓库均可用条件下的粗估,P2 的分发和系统准入会影响排期。首要决策不是先画多少按钮,而是团队能否提供适用研究机、是否能产出 Simulator 构建,以及目标包属于何种分发类型。

开发接入前还缺哪些具体材料?
  • Desktop 源码位置、技术栈、面板扩展点与已有 IPC 约束。
  • 研究 Mac 的系统准入条件、可用磁盘及内存预算。
  • 可测试的开发 IPA / Simulator .app、bundle ID 和最小验收路径。
  • 产品“无需操作”的定义:是否接受首次系统认证、预配置研究机或远端设备。

这些是进入实机集成阶段的输入,不影响本方案与调试包交付。

从源码到结论,可追溯。

检索日期:2026-09-24。Git 快照 3f7011406722576fb19bffbc8c30d8aa4c4916af。以下路径固定到同一提交;产品设计、性能目标与排期属于本方案建议。

  1. README、Package.swift、build.sh:当前架构、内置依赖与构建签名流程。
  2. CreateCLI、CreateOptions、Creator:参数、资源默认值、创建步骤及验证后停止。
  3. Compatibility:上游验证范围。请区分上游记录与本次实测。
  4. Host setup、HostPreflight:Recovery、私有 entitlement、AMFI 与预检边界。
  5. HTTP / WebSocket API、OpenAPI:VSOCK 1339、接口、版本与认证限制。
  6. HostAutomationServer、ScreenRecorder:JSON 行协议、截图与本地录屏。
  7. GuestAPI、GuestControl、IPA 安装实现:上传 guest 文件、安装、重签与注册。
  8. MIT LICENSE:开源仓库许可;不代表其他素材或宿主准入已获授权。
  9. Troubleshooting、当前中文版说明:故障处理与当前中文文档。
  10. idb:FBSimulatorControl、idb 仓库:Simulator 控制的开源参考。
  11. Apple:下载和安装 Xcode 组件:Simulator Runtime 的官方管理方式。