画布技能Skill:把 HTML 内容一键推送到 Mac、iOS、Android 上的“随身大屏”
- 它是什么:一个让 AI 把 HTML 内容直接渲染到已连接的 Otto 节点(Mac 应用、iOS、Android)画布视图上的技能,适用于游戏、可视化、仪表板和交互式演示。
- 核心能力:支持呈现、隐藏、导航、执行 JavaScript、截图五种画布操作,文件改动后可实时重载。
- 使用门槛:需要在
~/.otto/otto.json中开启canvasHost,并保证目标节点在线且具备画布能力。 - 最容易踩的坑:URL 必须与网关绑定模式匹配——绑定到 Tailscale 时,用
localhost访问必然白屏,要用 Tailscale 主机名。 - 适合谁:需要把生成的网页内容“投”到多端屏幕上验证或演示的开发者、数据分析师、AI 应用构建者。
1. 该技能叫什么?如何下载安装 AI 技能提升开发效率?
中文名:画布技能Skill 英文名:canvas 技能ID:13598
它要解决的问题很具体:AI 或开发者生成了 HTML 内容(一个小游戏、一张仪表板、一段交互演示),但内容只停留在本地文件或浏览器标签页里,无法方便地出现在手机、平板、另一台 Mac 的屏幕上。画布技能就是在“内容”和“屏幕”之间架起一条通道:画布主机服务器负责提供静态 HTML/CSS/JS 文件,节点桥接器把画布 URL 告知已连接的节点,节点应用再用 WebView 渲染内容。
架构上分三层:
画布主机服务器(HTTP 服务器,端口 18793)
↓
节点桥接器(TCP 服务器,端口 18790)
↓
节点应用(Mac / iOS / Android)
一键安装与生效验证的思路(具体安装命令与入口请以官方说明为准):
- 安装前提:已部署 Otto 环境,且至少有一个 Mac 应用、iOS 或 Android 节点连接到同一个节点桥接器;节点需要具备画布能力。
- 开启画布主机:在
~/.otto/otto.json中配置canvasHost(enabled、port、root、liveReload),并设置gateway.bind。默认端口为 18793,默认根目录为~/agent/canvas/。 - 验证服务是否启动:用
lsof -i :18793确认端口被监听,再用curl http://<hostname>:18793/__otto__/canvas/index.html直接拉取内容。默认的index.html自带桥接诊断,非常适合做第一次连通性测试。 - 验证节点是否在线:执行
otto nodes list,确认列表中能看到带画布功能的 Mac/iOS/Android 节点及其节点 ID。 - 验证端到端效果:执行一次
canvas action:present node:<node-id> target:<full-url>,节点屏幕上出现页面即代表安装生效。
整个安装过程没有复杂的编译环节,本质是“开配置 + 起服务 + 验连通”,一次配置好之后,后续每次只需要换 URL 即可。
2. 该技能的主要功能和特点
- 五种画布操作:
present(显示画布,可带目标 URL)、hide(隐藏画布)、navigate(导航到新 URL)、eval(在画布中执行 JavaScript)、snapshot(捕获画布截图)。意味着不仅能“投屏”,还能远程控制页面跳转、注入脚本、回传画面。 - 静态资源托管:从
canvasHost.root目录提供 HTML/CSS/JS,URL 前缀固定为/__otto__/canvas/(由CANVAS_HOST_PATH常量定义),子目录会自然映射,例如games/snake.html对应~/agent/canvas/games/snake.html。 - 实时重载(liveReload):默认开启,通过 chokidar 监视根目录变化,并向 HTML 文件注入 WebSocket 客户端,文件一保存,连接的画布自动刷新。这是相比“手动改完再手动刷新手机屏幕”最明显的效率优势。
- Tailscale 友好:
gateway.bind支持loopback、lan、tailnet、auto四种模式;auto按 Tailscale > LAN > loopback 的优先级选择最佳可用地址,跨网络访问不用自己搭内网穿透。 - 多端一致体验:同一份 HTML 可以投到 Mac、iOS、Android,省去为每类设备重写展示层的工作。
和普通工具比强在哪?普通浏览器预览只解决“本机看”,普通投屏只解决“画面镜像”,而画布技能解决的是“AI 可控的内容投放”——它能被 AI 通过统一操作指令调用,把生成、呈现、导航、截图串成一条自动化链路。
3. 如何使用该技能?
第 1 步:创建 HTML 内容
把文件放进画布根目录(默认 ~/agent/canvas/):
cat > ~/agent/canvas/my-game.html << 'HTML'
<!DOCTYPE html>
<html>
<head><title>My Game</title></head>
<body>
<h1>Hello Canvas!</h1>
</body>
</html>
HTML
第 2 步:确认网关绑定方式
cat ~/.otto/otto.json | jq '.gateway.bind'
第 3 步:构造正确的 URL
loopback:http://127.0.0.1:18793/__otto__/canvas/<file>.htmllan/tailnet/auto:http://<hostname>:18793/__otto__/canvas/<file>.html
需要 Tailscale 主机名时:
tailscale status --json | jq -r '.Self.DNSName' | sed 's/\.$//'
第 4 步:找到连接的节点
otto nodes list
第 5 步:呈现内容
canvas action:present node:<node-id> target:<full-url>
示例:
canvas action:present node:mac-63599bc4-b54d-4392-9048-b97abd58343a target:http://peters-mac-studio-1.sheep-coho.ts.net:18793/__otto__/canvas/snake.html
第 6 步:后续控制
canvas action:navigate node:<node-id> url:<new-url>
canvas action:snapshot node:<node-id>
canvas action:hide node:<node-id>
输入与输出说明:输入是“操作名 + 节点 ID +(可选)URL”;输出是节点端画布状态的改变——页面出现、跳转、截图回传或隐藏。画布会一直保持,直到执行 hide 或导航离开。
配置参考:
{
"canvasHost": {
"enabled": true,
"port": 18793,
"root": "/Users/you/agent/canvas",
"liveReload": true
},
"gateway": { "bind": "auto" }
}
4. 同类型竞品对比分析
| 方案名称 | 定位 | 核心功能 | 安装/使用门槛 | 适用场景 | 优势与不足 |
|---|---|---|---|---|---|
| 画布技能Skill(canvas) | AI 可调用的多端 HTML 投放通道 | present/hide/navigate/eval/snapshot、实时重载、Tailscale 绑定 | 中:需配置 otto.json 与节点连接 |
游戏与可视化演示、仪表板投放、AI 生成内容即时呈现 | 优势:操作可被 AI 编排、多端一致、支持截图回传;不足:依赖 Otto 节点生态,URL 与绑定模式强耦合,易因 localhost 误用白屏 |
| 本地浏览器直接打开文件 | 最轻量的预览方式 | 打开本地 HTML、开发者工具调试 | 极低 | 单人本机调试 | 优势:零配置;不足:无法投到手机/平板,无法被 AI 远程控制,无跨设备实时重载 |
| 屏幕共享 / 远程桌面 | 画面级镜像 | 整屏或窗口投送 | 中:需安装远程工具并授权 | 远程协助、临时演示 | 优势:通用性强;不足:传的是像素不是内容,分辨率与操作体验差,无法按页面粒度导航或执行 JS |
| 静态站点托管 + 手机浏览器 | 公网发布式预览 | 托管 HTML 并提供链接 | 中高:需部署、可能涉及公网暴露 | 对外分享、长期可访问页面 | 优势:链接即达、稳定;不足:发布链路长、私密内容不适合公网、缺少实时重载与截图回传 |
5. 该技能的典型应用场景与实际体验情况
场景一:小游戏与交互 Demo 的多端验证
角色:前端开发者或 AI 应用构建者。痛点:在 Mac 上跑得好好的小游戏,到了 iPhone 上触控和视口全乱。使用方式:把 snake.html 放进画布根目录,present 到 iOS 节点,改代码保存即自动重载。实际体验:实时重载是最大加分项,改一行样式就能在真机屏幕上看到结果;注意事项是保持 HTML 自包含(内联 CSS/JS)效果最佳,外部依赖路径要相对根目录写对。
场景二:数据仪表板投屏到会议室大屏
角色:数据分析师。痛点:想让仪表板出现在另一台 Mac 上循环展示,而不是每次手动打开浏览器输地址。使用方式:仪表板 HTML 放入根目录,先 present,需要换看板时用 navigate 切 URL。实际体验:一条指令完成切换,节奏很顺;需要注意的是画布会持续保持,演示结束后记得 hide。
场景三:AI 生成内容的即时可视化确认
角色:使用 AI 生成页面原型的用户。痛点:AI 输出了一大段 HTML,只能复制到本地文件再看效果。使用方式:写入画布根目录后直接 present,用 snapshot 抓图回传给模型做下一步迭代。实际体验:snapshot 让“生成—查看—修正”形成闭环,省掉大量复制粘贴;注意目前 A2UI JSON 推送仍在开发中,暂时需要用 HTML 文件方式。
场景四:内网与远程混合环境的演示
角色:需要跨网络演示的团队成员。痛点:手机不在同一局域网,或者公司网络限制多。使用方式:gateway.bind 设为 tailnet 或 auto,用 Tailscale 主机名构造 URL,节点自动收到可访问地址。实际体验:一次配好之后非常省心;注意事项是必须用完整主机名而非 localhost,这也是白屏问题最常见的根因。
整体上手难度:偏低到中等。配置文件结构简单,真正的学习曲线集中在“URL 与绑定模式如何匹配”这一处,理解了 canvasHostHostForBridge 源自 bridgeHost 这一点,多数问题就迎刃而解。
6. 该技能能为用户带来的价值
- 把“看效果”的循环从分钟级压到秒级:实时重载让保存即刷新,配合
snapshot回传画面,AI 迭代一次页面原型不再需要人工搬运文件、手动刷新、截图上传。 - 降低多端验证成本:一份 HTML 同时覆盖 Mac、iOS、Android,免去为每个平台单独准备预览环境的重复劳动。
- 降低远程演示门槛:借助 Tailscale 绑定,跨网络投放不需要额外搭建内网穿透或公网托管,也不用把私密内容发布到公网。
- 让 AI 具备“输出到屏幕”的最后一公里能力:present、navigate、eval、snapshot、hide 五个动作构成一个可编排的闭环,使“生成内容 → 呈现 → 观察 → 调整”真正自动化。
- 长期价值:画布根目录天然成为一个可复用的内容仓库,游戏、仪表板、演示页按子目录组织,随时按需投放;等 A2UI JSON 推送上线后,动态内容的投放路径还会进一步缩短。
7. 常见问题 FAQ
Q1:怎么安装这个技能?需要付费吗?
A:安装前提是已有可用的 Otto 环境与在线节点,然后在 ~/.otto/otto.json 中开启 canvasHost 并确认 gateway.bind,用 curl 验证 18793 端口可访问即可。至于是否需要付费、具体的安装入口与命令,请以官方说明为准,本文不做推测。
Q2:为什么节点上是白屏,内容加载不出来?
A:绝大多数情况是服务器绑定与节点期望的 URL 不匹配。排查顺序:cat ~/.otto/otto.json | jq '.gateway.bind' 看绑定模式 → lsof -i :18793 看端口是否在监听 → curl http://<hostname>:18793/__otto__/canvas/<file>.html 看内容能否取到。解决方案是使用与绑定模式匹配的完整主机名,不要用 localhost。
Q3:提示 “node required” 或 “node not connected” 怎么办?
A:“node required” 表示没指定节点,所有操作都必须带上 node:<node-id> 参数;“node not connected” 表示节点离线,用 otto nodes list 找出在线节点再重试。
Q4:改了 HTML,画布没更新?
A:依次确认三件事:配置里 liveReload 为 true;文件确实位于画布根目录内;日志中没有监视器(chokidar)相关错误。若仍不生效,可先 navigate 到新 URL 手动触发一次。
Q5:适合谁用,和普通浏览器预览或投屏工具怎么选? A:如果你只需要在本机看效果,本地浏览器最省事;如果要整屏镜像做远程协助,屏幕共享更通用;如果你希望内容被 AI 直接调用、能多端一致呈现、还能远程导航和截图回传,那么画布技能更合适。它尤其适合游戏与可视化演示、仪表板投放和 AI 生成原型的快速确认。