Releases: Daily-AC/wanctl
Release list
wanctl v0.11.0
v0.11.0 — 门户自己发一份 skill,一次授权最长可以给到一天
-
网页 AI 装一次就知道你这台实例在哪,不用每开一个新对话就重贴一遍连接说明。 门户在
/webfetch/skill上直接给出一份填好的 Agent Skill(markdown 原文),里面的 relay 地址和门户地址就是你这一台实例的地址,不是模板占位符。能装 skill 的宿主——Claude 项目、自定义 GPT、Kimi、Qwen——装一次以后,每次对话它自己就知道该去哪里找你的设备、按什么协议走。连接页上有「装成 skill」的入口,帮助页和发现文档(skill_url)也都指过去。同一轮还把发现文档里给 AI 的那段 instructions 改成和wanctl help --instructions用同一份目录渲染,两边从此不会各说各的;委托会话和 MCP 宿主规则不同的三条(exec 只能一次性、edit_text一次改一处、输出过长保留开头并取消命令)就写在对应的那几行旁边。 -
批准一次访问,最长可以给到 24 小时。 有效期原来卡在 60 分钟,批准页现在给四个预设——15 分钟、1 小时、4 小时、24 小时——外加一个自己填的分钟数,范围 1 到 1440,默认仍然是 15 分钟;点预设和手填走的是同一个输入框,服务端只会收到一个数。配套地,
exec的timeout_seconds上限从 1800 秒提到 14400 秒,一次授权允许的任务条数也不再是固定 64 条,而是按你批准的时长算,每小时 64 条。这么改是因为一次编译、一次渲染、一次安装可能要跑上几个小时,人过一阵回到同一个对话里读结果——以前授权先过期了,结果链接就打不开。代价写在批准页的小字里:授权开多久,AI 手里那条会话链接就在多久之内一直有效,要提前收回去「设置 → 访问令牌」。决定记在 ADR 0010。 -
安卓上两个开关都打开之后,提权命令不再被第三道关卡挡住。 以前在开着「自动放行所有命令」又开着「提权通道」的手机上,
wanctl exec --elevate每一条照样被拒,而且没有任何办法补上这个许可,提权在最需要它的无人值守设备上等于不能用。现在这种设备上的提权命令直接执行并记进日志。这是甲方 09-18 的决定:两个开关默认都关着,打开哪一个都得人动手,两个都打开本身就是许可。普通模式的设备一点没放松,只是修好了:提权请求现在会正常出现在门户的审批卡片上,并且带着要执行的命令文本——以前那张卡片只有一个没翻译的标签和一道破折号,根本没有可判断的东西。另外wanctl rules add --kind exec-elevated现在能建这一类规则;用--script发的命令记成规则时存的是脚本摘要(script:<解释器>:<完整 sha256>),卡片上会缩写的也只有真正的脚本,别的文本一律原样整条显示。还有一处:在安卓上用app、prop、screenshot而忘了加--elevate,现在直接告诉你要加这个参数,不再以「命令不存在」的样子回来。 -
中断一条持久会话里的命令,现在真的能把它停掉。 Ctrl-C,或者控制端的连接断了,设备端会把那个 shell 连同还留在它进程组(Windows 上是作业)里的东西一起 kill,整条会话销毁,下一次 exec 拿到的是一个全新的 shell。代价说在前面:那条会话的工作目录和环境变量没了,需要保留上下文就用
--oneshot,--oneshot的行为这次没有变。仍然跑得掉的是主动离开容器的进程:Unix 上setsid()、双 fork、以及更常见的setpgid()(作业控制set -m起的后台任务就是这种);Windows 上受控 shell 自己创建的进程一个也跑不掉,但它请系统里别的服务代为创建的进程不在这个作业里。决定记在 ADR 0011。 -
wanctl update在只做控制端的机器上不会再顺手起一个 agent。 那台机器装了 wanctl、登录了、只用来控制别人,更新完之后它还是只做控制端,配置目录一个字节都不会多出来。另一头也补上了:一个正在运行、但没把 pid 记在文件里的受控 agent,以前在更新时会被静默跳过重启,旧版本继续在跑还看不出来;现在这种情况会照常重启。 -
macOS 上截图失败,现在直接告诉你要去开哪个权限。 以前只回一句
screencapture failed: could not create image from display,看不出这其实是系统没给屏幕录制权限。现在报错里写清楚了:打开系统设置 → 隐私与安全性 → 屏幕录制,把 wanctl 或者启动 agent 的那个程序加进去并打开,然后重启 agent。 -
17 条工具说明重写成操作指南。 这些文字是 AI 读的,是它的操作手册,可这 17 条一直只是把参数表复述一遍。现在每条都回答三个问题:什么时候该用它而不是旁边那个(要字节用
push、要看文件用read而不是pull、长短不定的活先用exec_async)、拿到的结果是什么意思(控制端上rules和trust clients是空的很正常,轮询没有新输出不等于卡住)、报错之后该做什么,包括哪些错的正确反应是停下来问人。给 AI 的 instructions 里 REFUSALS 那行标题也改了:原来写「这些都不用重试」,底下四条却有两条明写着「然后重试」;现在说的是「都不能原样重试」——在批准、固定指纹、人做决定或者补上凭据之前,把同一次调用再发一遍没有意义。 -
慢速链路上 push 大文件,不再跑了几分钟之后以
tls: bad record MAC失败。 根子在 relay 的下行长轮询:字节一出队就写进响应,响应半路断了那段字节就永远没了,端到端的 TLS 流里出一个洞,两头看到的就是这条错。现在 relay 给每个下行分片编号,读的一方在下一次轮询里确认收到了哪一片,没确认的分片原样重发;单次响应最多 2 MiB,慢链路上一次也下得完;正常关闭的会话会留到两个方向都读空再收掉。新旧版本混用是安全的:任意一边是旧版,就退回原来的做法。
本次 relay、门户和受控端都建议升级:这一版改动了设备端的行为(提权判定、会话中断、传输确认)。传输层的确认在任意一边是旧版时会退回原来的做法,版本混着用是安全的。无数据库迁移,没有新增环境变量。安卓 APK 这次只改了文案字符串。
wanctl v0.10.0
v0.10.0 — wanctl 成为网页 AI 的外部 harness:原生 read / write / edit / screenshot,help 就是它的 system prompt
-
AI 看文件、改文件不再靠 cat 和 sed。 新增四个原生操作,设备端用 Go 直接做,不经过 shell,Linux、macOS、Windows、安卓行为完全一样:
read按行号分页(单次 256 KiB,永远在整行处截断并告诉你从第几行接着读),返回整个文件的 sha256;edit把一段旧文本换成新文本,旧文本必须在文件里唯一,可以带上刚才 read 到的 sha256 做校验,改错了就整体拒绝、文件一个字节不动;一次调用可以带多处修改,网页 AI 少点几次授权;write新建或整份覆盖文本文件,自动建父目录。二进制照旧走 push / pull。全部走设备原有的策略规则和审批,日志里记成文件事件。三个接入面都有:CLI(wanctl read / edit / write)、MCP(wanctl_read / wanctl_edit / wanctl_write,本机 stdio 和公网托管端点都有)、WebFetch(read_text加了offset/limit,新增edit_text)。 -
截图扩到桌面。
wanctl screenshot和wanctl_screenshot原来只支持安卓,现在 macOS、Windows、Linux 都能截,MCP 直接把图交给模型看。做界面、做游戏的时候,AI 终于能看到用户看到的东西,而不是只看文字状态。桌面截图和普通命令走同一道策略门,bypass 模式直接放行;安卓仍按提权命令管。 -
exec 输出太长时保留尾巴。 以前超过上限砍尾巴,报错恰恰都在尾巴上。现在保留最后一段,完整输出存在设备的临时目录里并告诉 AI 路径。
-
help 重写成「薄 MCP」。 光敲
wanctl只出一页索引;wanctl help exec给的是和 MCP 工具描述同一份文字:什么时候用、参数是什么、每条报错该怎么办。CLI、MCP、docs/contract.md三处出自同一份目录,测试保证不会漂移。MCP 连上时还会带一段二十来行的 instructions,就是这个 harness 的 system prompt:有哪些原语、怎么配合(起 dev server 用后台任务、看文件用 read、改文件用 edit、进项目先读 AGENTS.md)。 -
WebFetch 按强模型重写。 只服务 Qwen 3.8-Max、ChatGPT 这一档的模型:用户贴一句话进去,剩下的由 AI 带着走,人只需要点两次——批准设备访问、批准配对。命令可以跑到 30 分钟(以前 60 秒,Blender 建模直接超时),轮询 next_url 拿结果。安全规则一条没减;重放丢失响应的链接沿用同一个 rid,只有明确「什么都没执行」时才换新 rid,409 表示同一个 rid 换了参数、必须停下。
-
连接中途断了不再冤枉设备。 以前请求发出去之后连接断开,控制端一律报「设备版本太旧」;现在只有设备明确回「不认识这个操作」才这么说,其余情况报「结果未知,先 read 一遍比对 sha256 再决定要不要重试」,避免 AI 把已经写进去的修改再写一遍。
本次受控端要升级(新增了四种设备端操作)。开着自动更新的设备会自己升;没升的设备被 AI 调用 read / edit / write / screenshot 时会收到明确提示「请在设备上 wanctl update」,不会挂住。relay 和 portal 一起升级,无数据库迁移,没有新增环境变量。
wanctl v0.9.4
v0.9.4 — 网页 AI 自己走完设备身份确认,配对链接先看清状态再问你
- 首次让 AI 碰一台设备时会先撞上设备身份确认(TOFU 指纹固定),以前那条提示写的是「去跑
wanctl trust server」——可网页 AI 手里没有这个命令,它只能把「请在设备端确认指纹」转述给你,来回两三轮才想起自己就有对应的工具。现在通过托管端点返回的提示直接点名wanctl_trust_server,把目标和指纹按调用需要的形式写清楚,并告诉它不必先问你:MCP 宿主自己的授权弹窗就是那道人工关卡。指纹固定本身没有放松,变的只是谁来清掉第一次那一步。配套三处:wanctl_peers给每台设备标出identity: pinned还是unpinned,哪台还要过身份确认一眼看得出;指纹对不上时同时列出已固定的和这次出示的两个指纹,并要求 AI 停下来向你报告,而不是自作主张重新固定;在门户里解绑一台设备,托管端点上的指纹记忆也跟着忘掉——重装过的设备换了证书之后不再永远卡在「身份不符」,以前只能靠重启 relay 才能救回来。 - 从链接打开的配对确认页,现在开窗时先去问设备这条请求还在不在,再决定画什么:还等着答复就照旧给「信任 / 拒绝」两个按钮;这台控制端其实早就信任过了,就只给一个「好」并说明无需再操作;已过期、已被别人答过或从来不存在,同样只给一个「好」。以前不论哪种情况都是两个按钮,非得点下去才被告知这条请求已经死了。
- 托管的状态行不再报容器内的回环地址。开着托管 MCP 时
wanctl_status里的 relay 地址显示为对外的公开地址,AI 读到的就是它真能访问的那一个。
本次更新只需升级 relay 和 portal,无数据库迁移,也没有新增环境变量。受控端不受影响,不需要升级。
wanctl v0.9.3
v0.9.3 — 托管 MCP 端点支持 OAuth,网页 AI 点一次「允许」就能用
- ChatGPT、claude.ai 这类网页 AI 每调用一次工具就新开一次 MCP 会话,所以按会话存的登录在它们身上活不过一次调用——刚登录成功,下一个工具就报 LOGIN REQUIRED。现在托管端点按 MCP 授权规范支持 OAuth 2.1:连接器的鉴权方式选「OAuth」,它自己完成发现和注册,你在门户上照常 GitHub 登录、看清是哪个客户端、点一下「允许」,就结束了。没有 code 要复制,也没有来回粘贴。
- 授权跟着连接器走而不是跟着会话走,所以它每次新开会话都还是已登录状态,首次配对过的设备也不用反复确认指纹。每份授权在门户的访问令牌页里以
oauth:加客户端名字出现,随时可以吊销;让 AI 调wanctl_logout是同一件事。 - 不带 OAuth 的老路完全不变。Claude Code、Codex、Cursor 这些一个会话用到底的宿主,照旧
wanctl_login取一次性 code,行为和 v0.9.2 一模一样。
本次更新要升级 relay 和 portal,并且有数据库迁移(010),部署前按惯例先备份。relay 需要同时有数据库、WANCTL_PUBLIC_ORIGIN 和 WANCTL_PORTAL 才会打开 OAuth,缺一样就只保留会话登录,没有新增环境变量。受控端不受影响,不需要升级。
wanctl v0.9.2
v0.9.2 — MCP 端点改用 /mcp,过期的配对卡不再赖着
- 托管的 MCP 端点正式路径改为
https://relay.example.com/mcp,与各 AI 宿主的默认约定一致。/wanctl-mcp保留为别名,给边缘代理已经占用/mcp前缀的部署用;两条路径同一批会话。 - 配对请求过期(5 分钟)或已被答复后,设备不再把它留在状态快照里,门户上那张卡随下一轮刷新消失;对一条已失效的请求点「信任它」,门户明确提示「已过期或被人答过了」,而不是报成功。
- 从链接打开的配对确认页在设备答「已不存在」时自动收起,并支持 Esc 关闭,不再盖住底下真正的待审批清单。
本次更新只需升级 relay 和 portal,无数据库迁移。受控端会随自动更新拿到过期清理;旧版受控端照常工作,门户的提示对它们同样生效。
wanctl v0.9.1
v0.9.1 — 可独立发现、继续和诊断的 GET 接口
- 公共入口改为静态协议说明,不再返回会话票据。调用方通过
/webfetch/v1发现协议,用每次对话独立的随机标识创建申请,防止抓取缓存复用同一份授权。 - 门户新增“设置 → 连接网页 AI”,每次复制都会生成带独立网址的接入提示词,无需模型自行编造随机值。
- 直接返回完整的设备
target、工具参数 schema 和 GET 调用模板,无需猜测命名空间与设备 ID 的拼法。 - 申请、工具和任务页面提供含完整状态地址的继续指令,方便批准或配对后在下一轮对话继续。
- 网页抓取客户端能读到明确的错误正文;程序客户端使用
format=json时继续获得标准 HTTP 错误码。设备范围、撤销和重复请求保护保持生效。 - 已绑定其他账号的授权链接显示原因与恢复提示,不再只显示
delegation forbidden。增加不含票据和操作内容的诊断日志。 - 自部署 Compose 接通已有的 HTTP-MCP 入口及门户/中继地址配置,补充 stdio 与托管 MCP 的使用文档,登录说明不再限定某一种身份提供商。
本次更新只需升级 relay 和 portal,无新增数据库迁移;v0.9.0 受控端继续兼容。新客户端应读取 start_url_template,已有会话按原有效期继续使用。网页客户端仍需能够实时抓取指定 URL;支持联网搜索本身不保证具备这项能力。
wanctl v0.9.0
v0.9.0 — 网页 AI 可以通过 WebFetch 使用设备
- 新增可选的 WebFetch 接入层。 不支持 MCP、但能够抓取指定 URL 的网页 AI,可以申请临时使用 wanctl 设备,执行一次性命令、写入和读取文本文件。
- 授权仍在 wanctl 内完成。 设备主人登录门户,选择自有设备并批准 1–60 分钟的访问;首次连接继续使用原有配对流程。设备自己的规则和审批决定操作是否允许,临时使用者不能修改信任、规则或模式。
- 支持随时吊销。 访问令牌页面显示设备范围和到期状态。吊销或到期后,新操作和任务结果读取都会被拒绝;设备在等待人工审批后还会再次检查授权。
- 重复抓取不会自动重复执行。 任务在调用前写入持久账本。中断后无法确定结果的任务会标为 unknown,需要人工核对,不会自动重放。
- 审计保留授权归属。 设备日志记录授权、凭证与连接编号,便于确认是哪次网页 AI 会话执行了操作。
默认关闭,需要管理员配置 WebFetch 种子并升级 relay、portal 和受控端。旧受控端会拒绝委托连接,原有 CLI/MCP 使用不受影响。网页入口为中继域名下的 /webfetch。
本版本包含数据库迁移 009。若回滚至旧 relay,必须先吊销所有 delegated 令牌。关闭连接不能撤回已经完成的操作;在 bypass 模式的设备上授权使用,仍意味着授予该设备现有的广泛操作能力。
wanctl v0.8.2
v0.8.2 — 升级时不会再把设备停下来却起不回来
wanctl stop现在等 agent 真正放手才返回(最多 10 秒,超时就报错并且不再往下走)。以前它只管发停止信号就返回,于是wanctl update停旧 agent、换二进制、起新 agent 这一串里,新 agent 会撞上还没退干净的旧 agent 占着的配置目录锁,拿不到锁就直接退出——而上一步已经打印了「✓ 服务已转后台」。本机上真出过一次:设备从中继上掉线 50 分钟,直到手动wanctl start才回来。- agent 抢不到锁时会先等一小会儿(最多 5 秒)再退出,并且不再报「another agent is already running (pid 自己)」——
wanctl start是在子进程加锁之前就把它的 pid 写进agent.pid的,输不掉这一局的 agent 从那里读到的正是自己的号码,那句提示会让人去找一个根本不存在的进程。
无需任何操作;wanctl status 里「未运行」那行的提示也从 wanctl 改成了 wanctl start。
wanctl v0.8.1
v0.8.1 — 直接跑 wanctl 只打印帮助,接入设备改用 wanctl start
以前不带参数跑 wanctl 会「登录 + 把这台机器变成被控设备」。想看看这个命令是干嘛的、在自己只当控制端的电脑上敲一下 wanctl,那台电脑就被注册成了一台被控设备——这不是任何人敲那一下时想要的结果。
wanctl现在只打印帮助,外加一行本机状态(有没有登录、agent 有没有在跑),不做任何事,不写任何文件。wanctl start接手了登录那一步:没有令牌时它会开浏览器走门户登录、存下令牌,然后把 agent 转到后台。接入一台设备仍然是一条命令。wanctl login不变:只拿控制端的令牌,永远不会启动 agent。wanctl up已删除。它只是wanctl无参那条路的别名,没有别的东西在用它。
升级后要改的地方:接入设备的那一行从 wanctl 改成 wanctl start;只当控制端的机器用 wanctl login。已经在跑的 agent 不受影响。
wanctl v0.8.0
v0.8.0 — 共享设备继承主人的使用权,管理权是一个开关
以前把设备共享给好友要勾 exec / read / write 三个权限,而设备自己的模式和规则又会再判一遍,被共享方经常连不上、连上了也不知道能做什么。本版把共享改成一句话:被共享方像主人一样使用这台设备,能不能替主人管理它由一个开关决定。
- 共享即拥有使用权:执行命令、传文件、看活动日志,都按设备当前的模式和规则来(逐条确认就等主人审批,主人开了 bypass 大家都直接过)。不再有权限勾选框;旧的授权会在被共享方下一次连接时自动变成完整使用权。
- 「可管理」开关,默认关:打开后被共享方可以在门户和 CLI 里回答审批、修改规则、切换模式。主人在「共享授权」表里每条单独切换,CLI 用
wanctl share grant --manage或wanctl share manage --device D --to NS on|off。 - 永远只归主人:解除绑定、撤销共享、通知地址、飞书设置、ADB 配对。
- 门户共享设备页:未开管理时显示「活动」;开了管理后与主人看到的一样(待审批、信任与规则、模式、活动),页面标明设备属于谁。修复了直接打开共享设备链接时页面把它当成自己设备渲染的竞态(#48)。
wanctl update/start/status/stop判断 agent 是否在运行改为看 agent 持有的文件锁,不再只看agent.pid里的进程号:以前残留的 pid 文件遇上系统复用进程号,会让一台只做控制端的电脑在wanctl update后被当成被控端重新注册,wanctl stop也可能误杀无关进程。- 中继数据库迁移 008 为授权表加
manage列,默认关,已有共享不会自动获得管理权。
升级中继后被共享方无需操作;想让某位好友替你审批,去「共享授权」把那一行的「可管理」打开。