你启动一个任务,它跑了一阵,你去泡咖啡。回来时,代理已经等了十分钟,就为问你一句话:“改好了,接下来怎么处理?”
![]()
这个场景,是 Farol Remote 诞生的直接原因。它让你在手机上回答编码代理的问题,而任务继续跑在你的 Mac 或你自己的服务器上。
Farol 是一个为编码代理做的 macOS 终端。侧边栏列出每个会话,旁边一个小圆点:空闲时是空心,代理工作时呼吸般起伏,等你回复时泛起涟漪,完成后填满。它能告诉你代理需要你了——前提是你坐在 Mac 前。
于是思路很直接:把这个侧边栏装进口袋。看会话、读对话、点一下就能回答。
手机上能做什么
iPhone 应用按状态列出你的会话,点开是代理的对话,而不是一屏终端文字。代理请求批准或提问时,答案以按钮形式出现,一点就继续。你还能用斜杠命令回复、发截图给代理看、逐个文件查看改动、在某个项目里新开会话。
代理等待或完成时会通知你。锁屏上的实时活动会统计正在工作和等待的代理数量,应用关掉也照样更新。一部手机可以同时知道多台 Mac 和服务器,工作用的 Mac 和跑代理的服务器出现在同一个列表里,每个会话标注所属主机。
难的是中间那一段
手机和 Mac 没法在互联网上直接对话。Mac 躲在家用路由器后面,手机在 4G 上,谁也够不着谁。所以中间需要一个中继:两边都向外连到它,由它转发消息。
问题随之而来。如果一切都经过一台服务器,那这台服务器能看到什么?这些消息是你的代码、你的提示词,以及一个能往你终端里打字的手机。作者不想让答案变成“相信我”。
目标定为:中继转发它读不了的消息,并且一条都不存。
配对从二维码开始。Mac 上在设置里打开 Remote,按下显示代码;手机上扫码。这个码携带三样东西:中继地址、Mac 的公钥,以及专为这个码生成的密钥。码里 # 之后的部分永远不会发给服务器,所以密钥到不了中继,中继也就无法自己配对一台设备。手机回一条密封消息,同时证明两件事:它持有声称的密钥,并且它见过那个密钥。一个码只能用一次,有效期两分钟。之后,Mac 知道手机的公钥,手机知道 Mac 的公钥。
每次连接时,双方明文打招呼,带上公钥和为本次连接生成的随机数。然后每个方向变成独立的 HPKE 流,密封到对方的密钥上,并用自己的密钥签名。作者用的是 CryptoKit 的 Curve25519_SHA256_ChachaPoly 套件。握手信息里包含双方的随机数,因此旧连接的录制内容无法在新连接上打开,消息也只能按密封顺序解开。有一条打不开,连接就终止。
中继实际看到的东西
基本只有字节。它看到一个公钥,以及一个房间名——房间名是主机公钥的哈希。Mac 和它的手机靠这个互相找到,而中继不知道它们是谁。它还能看到加密消息以及消息有多大。它不存任何内容,日志里只有总量。
通知这块有点意思。作者想要代理等待时收到通知,哪怕应用关着。这意味着苹果要推送,而总得有什么东西去请求苹果。Mac 请求中继转发一条推送,中继看到的是手机的通知令牌和一个词:等待或完成。具体是哪个会话,密封传输,只有手机能看。实时活动同理,主机通过中继保持更新,所以应用休眠时锁屏上的计数仍在动。
有些人把代理跑在一台常开的机器上,好合上笔记本。为此有个 farol-host,一个小型 Go 命令行工具。一条 curl 命令安装,setup 会接好 Claude Code 和 Codex 的钩子,用 systemd 让 farol-host 常驻,并显示一个二维码供扫描。之后那台机器上每个 tmux 窗口都是手机上的一个会话,就像 Mac 上 Farol 里的一个标签页。
Mac 和 iPhone 共用一个 Swift 包,服务器用 Go 重写了同一套协议。同一套加密和消息有两份实现,很容易出现只在真机上才暴露的 bug,所以让它们互相校验。Swift 测试把样例消息和一段密封对话写成 JSON 文件,Go 测试打开这些文件,必须一字不差地读出来。消息一改,就重新生成。Go 和 Swift 只要有一个字段对不上,测试会在任何手机看到之前失败。
还没覆盖的部分
作者选择把话说在前面。如果主机的密钥日后被盗,从手机发往该主机的录制流量可能被读取。主机目前也还不向中继证明自己,所以知道某个房间名的人可以把真正的主机挤下线。他们读不到也发不了任何东西,但这仍在他的待办清单上。配对和加密还没有经过外部审查,如果这是你的领域,作者欢迎第二双眼睛——所有代码刻意放在一个小仓库里。
Farol 免费且开源,iPhone 应用也免费,正在 TestFlight 上公测。在 Farol 里打开设置,选择 Remote,开启,按下显示代码,用应用扫码即可。安全相关的部分在 farol-remote 仓库:Swift 包、中继和 farol-host。下次代理在你外出时问你问题,直接回答就行。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.