远程控制与移动端
Control Center 是一款桌面应用,但它所跟踪的工作不会在你离开书桌时停下来。
远程控制借助 Remote——位于
remote.usectrl.dev 的伴侣应用——把你的手机与 cc_server 配对,让你可以在那里
跟进机群:阅读消息与工单、回复智能体、分拣新闻流,而服务器上的音频、转录、
源代码和凭据始终不会离开服务器。
可以把它看作主界面的伴侣应用,以读取为主。它并不打算取代完整的桌面客户端。
传输方式
标题为“传输方式”的部分手机通过 WebSocket 访问 cc_server:要么是直连(回环、LAN、tailnet 或
wss://),要么是信令代理上需邀请才能加入的房间,由该代理转发密封帧。这里没有
点对点的数据通道。
手机能做什么
标题为“手机能做什么”的部分已配对的手机只能触达服务器表面里很小、且有意划定的一块:
- 读取工单、智能体、空间及其消息,以及你的新闻流
- 回复:在空间中发送消息、更新或分配工单、把文章标为已读或已保存
- 运行剧本:用参数实例化一个已保存的计划模板。它只会_提出_一个计划;在 操作者在完整客户端的 Plan Studio 中批准之前,不会有任何执行或花费
- 切换工作区,在手机自己的选择器里
大致就这些。相比完整客户端,手机是权限更低的主体。它不能启动进程、消耗 LLM 预算、推送到 GitHub,也不能创建工作区。它为何是被真正强制执行而不只是设计 意图,见访问模型。
链路是如何建立的
标题为“链路是如何建立的”的部分连接依托一条经代理中转的中继:服务器作为所有者加入 wss:// 代理上一个
需邀请才能进入的房间,而每个已配对客户端——桌面端、Web、手机——都凭一个有期限
的准入令牌加入同一个房间。有三部分共同起作用:
| 组成部分 | 作用 |
|---|---|
| Remote(手机应用) | 伴侣 Web 应用,默认托管在 remote.usectrl.dev,也可自托管。它在浏览器中加载,把配对记录保存在 IndexedDB 中。 |
| 中继代理 | 一条无状态的 wss:// 中继(cc_signaling_server),托管 N 方房间。它只承载不透明的帧:每个负载都在手机与服务器之间端到端密封,因此代理既看不到应用数据,也看不到配对密钥,更不会解释它转发的任何内容。 |
cc_server |
房间的所有者。它通过其他所有客户端所用的同一个调度器来应答手机的调用。 |
一次配对邀约携带一个连接描述符,列出通往服务器的每条路径(LAN、tailnet、
公共 wss://、中继)以及服务器的身份指纹。手机的解析器会选出最好的可达路径,
并在首次连接时固定该指纹(TOFU);即使不存在直连路径,中继也能保证连通,同时
始终无法读取流量。
配对负载是什么
标题为“配对负载是什么”的部分配对凭据由应用生成,并以深链接的形式交付;具体步骤见 配对设备。这里重要的是它的结构。
https://<pwa-host>/#<payload>负载位于 URL 的片段中,也就是 # 之后、浏览器从不发给服务器的那一段,因此
PWA 的 HTTPS 主机也看不到它。它携带了手机访问服务器并证明自己身份所需的一切:
连接描述符(每条路径加上身份指纹)、一个新生成的设备 id、一个 32 字节的预共享
密钥,以及一个过期时间戳。手机会解码它,在本地保存配对记录,并去掉片段,让密钥
从 URL 中消失。
负载有两种形态,二者不可互换。从应用内配对面板生成的手机二维码就是上面那种
v2 PairingPayload,指向 Remote PWA 主机。cc_server pair --client-url 发出的
是另一种更旧的 v1 链接({s, i, k} —— 服务器 URL、设备 id、密钥),只面向
Web 客户端。
两者的有效期也不同,这一点很容易搞错:
| 生成方式 | 凭据有效期 |
|---|---|
应用内配对面板(pairing.mint) |
始终为 30 天 |
命令行上的 cc_server pair |
无 —— 凭据不会过期 |
访问模型
标题为“访问模型”的部分已配对的设备是经过身份验证但不受信任的。若干相互独立的关卡,让一次获批 (或泄露)的配对不会变成对服务器的完全控制。
1. 边界是成员身份,而不是配对
标题为“1. 边界是成员身份,而不是配对”的部分有效的配对密钥只能证明你是_哪台设备_。你可以读取或修改什么,由你的工作区 角色决定——每次调用都会重新解析——凡涉及仓库内容的操作,还要看按仓库授予的 权限。设备持有完全有效的密钥,但其所属用户不是所指定工作区的成员时,会被拒绝并 提示 “Not a member of this workspace”。
角色下限由操作的类型推导,除非操作自己声明:读取需要 guest,变更需要
member,破坏性操作需要 admin。
2. 手机属于更低的会话层级
标题为“2. 手机属于更低的会话层级”的部分除角色检查之外,手机会话所携带的能力也低于桌面端或 Web 会话。声明为仅限完整 客户端的操作,会在处理程序运行之前就对手机拒绝,无论其背后的用户权限多高:生成、 列出、重命名和吊销设备配对;读取和设置隧道连接;服务器备份与工作区导出/导入; 进程检测与终止;适配器探测;服务器设置;SSO 管理;机群控制;以及接管或交回 正在运行的智能体。
3. 默认拒绝的工具允许列表
标题为“3. 默认拒绝的工具允许列表”的部分具体到 MCP 工具面(tools/call),哪些工具可以被手机调用,由一份默认拒绝的
允许列表决定。未列入的工具在运行之前就会被拒绝。这份列表以读取和观察为主,另加
少量仅限本地的写入——一条消息、一次工单更新、一个文章标记——它们不消耗
LLM 预算、不启动进程,也不接触任何外部系统。
例如被拒绝的有:向智能体咨询、启动 AI 审查、终止智能体、把审查发布到 GitHub、 招聘或解雇智能体、创建工作区。
4. 按调用限定工作区范围
标题为“4. 按调用限定工作区范围”的部分服务器不保存“当前工作区”。它按设计是无状态的:每个以工作区为作用域的调用
都必须在其参数中给出目标的 workspace_id,一旦缺少该参数,或它指向一个服务器
未注册的工作区,调度器就会直接拒绝这次调用——这发生在任何数据库被打开之前。
因此手机永远无法继承或漂移到另一个客户端的作用域,指定一个外来的工作区也没有用,
因为第 1 道关卡里的成员身份检查仍然适用。这与产品其余部分强制执行的
工作区隔离是同一个不变式。
5. 以预共享密钥为密钥的端到端密封帧
标题为“5. 以预共享密钥为密钥的端到端密封帧”的部分手机与服务器之间的每一帧都用配对密钥密封;准入令牌只能让客户端进入房间,它不 解密任何东西。代理转发的只是密文,永远看不到密钥。已吊销的设备会发现自己的凭据 早已消失,因此它在重新连接时失败即关闭。
由应用生成的凭据有 30 天的期限;超过之后,连接关卡会判定它失败,手机必须重新 配对。吊销是实时的:服务器监视设备表,会在几秒内断开已吊销设备的现有会话,而不是 等它下次连接。
6. 按主体限流
标题为“6. 按主体限流”的部分滑动窗口限流器把远程工具流量限制在每分钟 120 次调用,并对变更类操作再加一个更严 的每分钟 30 次子上限。配额属于主体,而不是会话:你的三台设备共用同一份额度, 因此被劫持的客户端无法通过多开会话来换取余量,一个吵闹的成员也无法让其他人挨饿。
7. 什么也学不到的代理
标题为“7. 什么也学不到的代理”的部分中继代理被刻意做得笨拙:它托管房间、转发密封帧,不保存任何账户、应用数据或密钥。 房间需邀请才能加入,而且是临时的。应用数据、音频、转录、源代码和凭据全都留在 服务器上。
实时更新
标题为“实时更新”的部分配对之后,手机会以通知帧的形式收到实时更新——新的智能体消息、分配给你的工单、 状态变化——与桌面端自己的通知如出一辙。服务器把这些帧广播给每个已连接的会话, 工作区过滤在客户端一侧应用,因此你看到的内容被限定在你正在查看的那个工作区。
它在哪里
标题为“它在哪里”的部分| 界面 | 显示内容 |
|---|---|
设置 → 你 → 你的设备(/workspaces/:workspaceId/settings/you/devices) |
已配对客户端及其实时状态,另有配对新客户端(网页浏览器、桌面应用或手机)和吊销 |
同一个面板也能为第二个浏览器或桌面应用生成配对,并不只限于手机——流程完全相同, 只有深链接不同。
另请参阅
标题为“另请参阅”的部分- 工作区与隔离:它所依赖的按调用作用域
- 多人协作——身份、成员身份与在线状态:角色、成员身份与仓库权限
- 部署与客户端:远程控制在各客户端层级中的位置
- 架构:远程控制在技术栈中的位置
- 配对设备