画布技能Skill canvas

Canvas技能是一个用于在连接的Otto节点(Mac应用、iOS、Android)上显示HTML内容的工具,适用于游戏开发、数据可视化、仪表板展示和交互式演示。关键词:HTML显示、跨平台开发、游戏、数据可视化、仪表板、交互式演示、Web内容展示。

前端开发 0 次安装 0 次浏览 更新于 3/24/2026

name: canvas description: “在连接的Otto节点(Mac应用、iOS、Android)上显示HTML内容。用于游戏、可视化、仪表板和交互式演示。”

Canvas技能

在连接的Otto节点(Mac应用、iOS、Android)上显示HTML内容。

概述

画布工具让您在任何连接节点的画布视图上呈现web内容。适用于:

  • 显示游戏、可视化、仪表板
  • 展示生成的HTML内容
  • 交互式演示

工作原理

架构

┌─────────────────┐     ┌──────────────────┐     ┌─────────────┐
│  画布主机服务器  │────▶│    节点桥接器    │────▶│   节点应用   │
│  (HTTP服务器)   │     │  (TCP服务器)    │     │ (Mac/iOS/   │
│  端口18793      │     │  端口18790      │     │  Android)   │
└─────────────────┘     └──────────────────┘     └─────────────┘
  1. 画布主机服务器:从canvasHost.root目录提供静态HTML/CSS/JS文件
  2. 节点桥接器:将画布URL通信给连接的节点
  3. 节点应用:在WebView中渲染内容

Tailscale集成

画布主机服务器基于gateway.bind设置绑定:

绑定模式 服务器绑定到 画布URL使用
loopback 127.0.0.1 localhost(仅本地)
lan LAN接口 LAN IP地址
tailnet Tailscale接口 Tailscale主机名
auto 最佳可用 Tailscale > LAN > loopback

关键点: canvasHostHostForBridge源自bridgeHost。当绑定到Tailscale时,节点接收的URL类似:

http://<tailscale-hostname>:18793/__otto__/canvas/<file>.html

这就是为什么localhost URL不工作——节点从桥接器接收Tailscale主机名!

操作

操作 描述
present 显示画布,可选目标URL
hide 隐藏画布
navigate 导航到新URL
eval 在画布中执行JavaScript
snapshot 捕获画布截图

配置

~/.otto/otto.json中:

{
  "canvasHost": {
    "enabled": true,
    "port": 18793,
    "root": "/Users/you/agent/canvas",
    "liveReload": true
  },
  "gateway": {
    "bind": "auto"
  }
}

实时重载

liveReload: true(默认)时,画布主机:

  • 监视根目录变化(通过chokidar)
  • 将WebSocket客户端注入HTML文件
  • 文件变化时自动重载连接的画布

适用于开发!

工作流程

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. 找到您的画布主机URL

检查网关绑定方式:

cat ~/.otto/otto.json | jq '.gateway.bind'

然后构建URL:

  • loopbackhttp://127.0.0.1:18793/__otto__/canvas/<file>.html
  • lan/tailnet/autohttp://<hostname>:18793/__otto__/canvas/<file>.html

找到Tailscale主机名:

tailscale status --json | jq -r '.Self.DNSName' | sed 's/\.$//'

3. 找到连接的节点

otto nodes list

查找具有画布功能的Mac/iOS/Android节点。

4. 呈现内容

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

5. 导航、截图或隐藏

canvas action:navigate node:<node-id> url:<new-url>
canvas action:snapshot node:<node-id>
canvas action:hide node:<node-id>

调试

白屏/内容未加载

原因: 服务器绑定与节点期望的URL不匹配。

调试步骤:

  1. 检查服务器绑定:cat ~/.otto/otto.json | jq '.gateway.bind'
  2. 检查画布端口:lsof -i :18793
  3. 直接测试URL:curl http://<hostname>:18793/__otto__/canvas/<file>.html

解决方案: 使用与绑定模式匹配的完整主机名,而不是localhost。

"node required"错误

始终指定node:<node-id>参数。

"node not connected"错误

节点离线。使用otto nodes list查找在线节点。

内容未更新

如果实时重载不工作:

  1. 检查配置中liveReload: true
  2. 确保文件在画布根目录
  3. 检查日志中的监视器错误

URL路径结构

画布主机从/__otto__/canvas/前缀提供内容:

http://<host>:18793/__otto__/canvas/index.html  → ~/agent/canvas/index.html
http://<host>:18793/__otto__/canvas/games/snake.html → ~/agent/canvas/games/snake.html

/__otto__/canvas/前缀由CANVAS_HOST_PATH常量定义。

提示

  • 保持HTML自包含(内联CSS/JS)以获得最佳效果
  • 使用默认index.html作为测试页面(包含桥接诊断)
  • 画布持续直到hide或导航离开
  • 实时重载使开发快速——只需保存即可更新!
  • A2UI JSON推送正在开发中——暂时使用HTML文件