mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-25 19:58:38 +00:00
Docs: add zh-CN translations
This commit is contained in:
77
docs/zh-CN/platforms/mac/bundled-gateway.md
Normal file
77
docs/zh-CN/platforms/mac/bundled-gateway.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
read_when:
|
||||
- 打包 OpenClaw.app
|
||||
- 调试 macOS gateway launchd 服务
|
||||
- 为 macOS 安装 gateway CLI
|
||||
summary: macOS 上的 Gateway 运行时(外部 launchd 服务)
|
||||
title: macOS 上的 Gateway
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:27Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 4a3e963d13060b123538005439213e786e76127b370a6c834d85a369e4626fe5
|
||||
source_path: platforms/mac/bundled-gateway.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# macOS 上的 Gateway(外部 launchd)
|
||||
|
||||
OpenClaw.app 不再捆绑 Node/Bun 或 Gateway 运行时。macOS 应用
|
||||
要求**外部**安装 `openclaw` CLI,不会将 Gateway 作为子进程启动,而是管理一个
|
||||
按用户配置的 launchd 服务来保持 Gateway 运行(如果本地已有 Gateway 在运行,则会连接到现有实例)。
|
||||
|
||||
## 安装 CLI(本地模式必需)
|
||||
|
||||
Mac 上需要 Node 22+,然后全局安装 `openclaw`:
|
||||
|
||||
```bash
|
||||
npm install -g openclaw@<version>
|
||||
```
|
||||
|
||||
macOS 应用的 **Install CLI** 按钮通过 npm/pnpm 执行相同的安装流程(不建议使用 bun 作为 Gateway 运行时)。
|
||||
|
||||
## Launchd(Gateway 作为 LaunchAgent)
|
||||
|
||||
标签:
|
||||
|
||||
- `bot.molt.gateway`(或 `bot.molt.<profile>`;旧版 `com.openclaw.*` 可能仍然存在)
|
||||
|
||||
Plist 位置(按用户):
|
||||
|
||||
- `~/Library/LaunchAgents/bot.molt.gateway.plist`
|
||||
(或 `~/Library/LaunchAgents/bot.molt.<profile>.plist`)
|
||||
|
||||
管理者:
|
||||
|
||||
- macOS 应用在本地模式下负责 LaunchAgent 的安装/更新。
|
||||
- CLI 也可以安装它:`openclaw gateway install`。
|
||||
|
||||
行为:
|
||||
|
||||
- "OpenClaw Active" 启用/禁用 LaunchAgent。
|
||||
- 退出应用**不会**停止 Gateway(launchd 会保持其运行)。
|
||||
- 如果配置端口上已有 Gateway 在运行,应用会连接到该实例,而不是启动新的。
|
||||
|
||||
日志:
|
||||
|
||||
- launchd 标准输出/错误:`/tmp/openclaw/openclaw-gateway.log`
|
||||
|
||||
## 版本兼容性
|
||||
|
||||
macOS 应用会将 Gateway 版本与自身版本进行比对。如果不兼容,请更新全局 CLI 以匹配应用版本。
|
||||
|
||||
## 冒烟测试
|
||||
|
||||
```bash
|
||||
openclaw --version
|
||||
|
||||
OPENCLAW_SKIP_CHANNELS=1 \
|
||||
OPENCLAW_SKIP_CANVAS_HOST=1 \
|
||||
openclaw gateway --port 18999 --bind loopback
|
||||
```
|
||||
|
||||
然后:
|
||||
|
||||
```bash
|
||||
openclaw gateway call health --url ws://127.0.0.1:18999 --timeout 3000
|
||||
```
|
||||
127
docs/zh-CN/platforms/mac/canvas.md
Normal file
127
docs/zh-CN/platforms/mac/canvas.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
read_when:
|
||||
- 实现 macOS Canvas 面板
|
||||
- 为可视化工作区添加智能体控制
|
||||
- 调试 WKWebView canvas 加载问题
|
||||
summary: 智能体控制的 Canvas 面板,通过 WKWebView + 自定义 URL scheme 嵌入
|
||||
title: Canvas
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:34Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: e39caa21542e839d9f59ad0bf7ecefb379225ed7e8f00cd59131d188f193bec6
|
||||
source_path: platforms/mac/canvas.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Canvas(macOS 应用)
|
||||
|
||||
macOS 应用使用 `WKWebView` 嵌入了一个智能体控制的 **Canvas 面板**。它是一个轻量级的可视化工作区,用于 HTML/CSS/JS、A2UI 以及小型交互式 UI 界面。
|
||||
|
||||
## Canvas 的存储位置
|
||||
|
||||
Canvas 状态存储在 Application Support 目录下:
|
||||
|
||||
- `~/Library/Application Support/OpenClaw/canvas/<session>/...`
|
||||
|
||||
Canvas 面板通过**自定义 URL scheme** 提供这些文件:
|
||||
|
||||
- `openclaw-canvas://<session>/<path>`
|
||||
|
||||
示例:
|
||||
|
||||
- `openclaw-canvas://main/` → `<canvasRoot>/main/index.html`
|
||||
- `openclaw-canvas://main/assets/app.css` → `<canvasRoot>/main/assets/app.css`
|
||||
- `openclaw-canvas://main/widgets/todo/` → `<canvasRoot>/main/widgets/todo/index.html`
|
||||
|
||||
如果根目录下不存在 `index.html`,应用会显示一个**内置脚手架页面**。
|
||||
|
||||
## 面板行为
|
||||
|
||||
- 无边框、可调整大小的面板,锚定在菜单栏(或鼠标光标)附近。
|
||||
- 按会话记忆大小/位置。
|
||||
- 本地 canvas 文件变更时自动重新加载。
|
||||
- 同一时间只显示一个 Canvas 面板(根据需要切换会话)。
|
||||
|
||||
可以在设置 → **允许 Canvas** 中禁用 Canvas。禁用后,canvas 节点命令返回 `CANVAS_DISABLED`。
|
||||
|
||||
## 智能体 API 接口
|
||||
|
||||
Canvas 通过 **Gateway WebSocket** 暴露,因此智能体可以:
|
||||
|
||||
- 显示/隐藏面板
|
||||
- 导航到路径或 URL
|
||||
- 执行 JavaScript
|
||||
- 捕获快照图像
|
||||
|
||||
CLI 示例:
|
||||
|
||||
```bash
|
||||
openclaw nodes canvas present --node <id>
|
||||
openclaw nodes canvas navigate --node <id> --url "/"
|
||||
openclaw nodes canvas eval --node <id> --js "document.title"
|
||||
openclaw nodes canvas snapshot --node <id>
|
||||
```
|
||||
|
||||
注意事项:
|
||||
|
||||
- `canvas.navigate` 接受**本地 canvas 路径**、`http(s)` URL 和 `file://` URL。
|
||||
- 如果传入 `"/"`,Canvas 会显示本地脚手架或 `index.html`。
|
||||
|
||||
## Canvas 中的 A2UI
|
||||
|
||||
A2UI 由 Gateway canvas 主机托管,并在 Canvas 面板内渲染。当 Gateway 广播 Canvas 主机时,macOS 应用在首次打开时会自动导航到 A2UI 主机页面。
|
||||
|
||||
默认 A2UI 主机 URL:
|
||||
|
||||
```
|
||||
http://<gateway-host>:18793/__openclaw__/a2ui/
|
||||
```
|
||||
|
||||
### A2UI 命令(v0.8)
|
||||
|
||||
Canvas 当前接受 **A2UI v0.8** 服务端→客户端消息:
|
||||
|
||||
- `beginRendering`
|
||||
- `surfaceUpdate`
|
||||
- `dataModelUpdate`
|
||||
- `deleteSurface`
|
||||
|
||||
不支持 `createSurface`(v0.9)。
|
||||
|
||||
CLI 示例:
|
||||
|
||||
```bash
|
||||
cat > /tmp/a2ui-v0.8.jsonl <<'EOFA2'
|
||||
{"surfaceUpdate":{"surfaceId":"main","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","content"]}}}},{"id":"title","component":{"Text":{"text":{"literalString":"Canvas (A2UI v0.8)"},"usageHint":"h1"}}},{"id":"content","component":{"Text":{"text":{"literalString":"If you can read this, A2UI push works."},"usageHint":"body"}}}]}}
|
||||
{"beginRendering":{"surfaceId":"main","root":"root"}}
|
||||
EOFA2
|
||||
|
||||
openclaw nodes canvas a2ui push --jsonl /tmp/a2ui-v0.8.jsonl --node <id>
|
||||
```
|
||||
|
||||
快速冒烟测试:
|
||||
|
||||
```bash
|
||||
openclaw nodes canvas a2ui push --node <id> --text "Hello from A2UI"
|
||||
```
|
||||
|
||||
## 从 Canvas 触发智能体运行
|
||||
|
||||
Canvas 可以通过深层链接触发新的智能体运行:
|
||||
|
||||
- `openclaw://agent?...`
|
||||
|
||||
示例(在 JS 中):
|
||||
|
||||
```js
|
||||
window.location.href = "openclaw://agent?message=Review%20this%20design";
|
||||
```
|
||||
|
||||
除非提供有效密钥,否则应用会提示确认。
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
- Canvas scheme 阻止目录遍历;文件必须位于会话根目录下。
|
||||
- 本地 Canvas 内容使用自定义 scheme(无需回环服务器)。
|
||||
- 仅在显式导航时才允许外部 `http(s)` URL。
|
||||
62
docs/zh-CN/platforms/mac/child-process.md
Normal file
62
docs/zh-CN/platforms/mac/child-process.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
read_when:
|
||||
- 将 Mac 应用与 Gateway 生命周期集成
|
||||
summary: macOS 上的 Gateway 生命周期(launchd)
|
||||
title: Gateway 生命周期
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:36Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 9b910f574b723bc194ac663a5168e48d95f55cb468ce34c595d8ca60d3463c6a
|
||||
source_path: platforms/mac/child-process.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# macOS 上的 Gateway 生命周期
|
||||
|
||||
macOS 应用默认**通过 launchd 管理 Gateway**,不会将 Gateway 作为子进程启动。它首先尝试连接到已在配置端口上运行的 Gateway;如果无法连接,则通过外部 `openclaw` CLI(无内嵌运行时)启用 launchd 服务。这为你提供了可靠的登录自启动和崩溃后自动重启。
|
||||
|
||||
子进程模式(由应用直接启动 Gateway)**目前未使用**。如果你需要与 UI 更紧密的耦合,请在终端中手动运行 Gateway。
|
||||
|
||||
## 默认行为(launchd)
|
||||
|
||||
- 应用安装一个标签为 `bot.molt.gateway` 的用户级 LaunchAgent(使用 `--profile`/`OPENCLAW_PROFILE` 时为 `bot.molt.<profile>`;兼容旧版 `com.openclaw.*`)。
|
||||
- 当启用本地模式时,应用会确保 LaunchAgent 已加载,并在需要时启动 Gateway。
|
||||
- 日志写入 launchd Gateway 日志路径(可在调试设置中查看)。
|
||||
|
||||
常用命令:
|
||||
|
||||
```bash
|
||||
launchctl kickstart -k gui/$UID/bot.molt.gateway
|
||||
launchctl bootout gui/$UID/bot.molt.gateway
|
||||
```
|
||||
|
||||
运行命名配置文件时,请将标签替换为 `bot.molt.<profile>`。
|
||||
|
||||
## 未签名的开发构建
|
||||
|
||||
`scripts/restart-mac.sh --no-sign` 用于在没有签名密钥时进行快速本地构建。为防止 launchd 指向未签名的中继二进制文件,它会:
|
||||
|
||||
- 写入 `~/.openclaw/disable-launchagent`。
|
||||
|
||||
已签名的 `scripts/restart-mac.sh` 运行会在检测到该标记文件时清除此覆盖。手动重置方法:
|
||||
|
||||
```bash
|
||||
rm ~/.openclaw/disable-launchagent
|
||||
```
|
||||
|
||||
## 仅连接模式
|
||||
|
||||
要强制 macOS 应用**永不安装或管理 launchd**,请使用 `--attach-only`(或 `--no-launchd`)启动。这会设置 `~/.openclaw/disable-launchagent`,使应用仅连接到已运行的 Gateway。你也可以在调试设置中切换相同的行为。
|
||||
|
||||
## 远程模式
|
||||
|
||||
远程模式不会启动本地 Gateway。应用使用 SSH 隧道连接到远程主机,并通过该隧道进行通信。
|
||||
|
||||
## 为何优先选择 launchd
|
||||
|
||||
- 登录时自动启动。
|
||||
- 内置重启/KeepAlive 语义。
|
||||
- 可预测的日志和进程监管。
|
||||
|
||||
如果将来再次需要真正的子进程模式,应将其作为独立的、明确的开发专用模式进行文档记录。
|
||||
109
docs/zh-CN/platforms/mac/dev-setup.md
Normal file
109
docs/zh-CN/platforms/mac/dev-setup.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
read_when:
|
||||
- 设置 macOS 开发环境
|
||||
summary: 面向 OpenClaw macOS 应用开发者的设置指南
|
||||
title: macOS 开发环境设置
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:41Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 4ea67701bd58b7512f945fce58d79e1b3d990fbf45183323a1e3ab9688827623
|
||||
source_path: platforms/mac/dev-setup.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# macOS 开发者设置
|
||||
|
||||
本指南介绍从源代码构建和运行 OpenClaw macOS 应用的必要步骤。
|
||||
|
||||
## 前提条件
|
||||
|
||||
在构建应用之前,请确保已安装以下内容:
|
||||
|
||||
1. **Xcode 26.2+**:Swift 开发所需。
|
||||
2. **Node.js 22+ & pnpm**:Gateway、CLI 和打包脚本所需。
|
||||
|
||||
## 1. 安装依赖
|
||||
|
||||
安装项目的全部依赖:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
## 2. 构建和打包应用
|
||||
|
||||
要构建 macOS 应用并将其打包为 `dist/OpenClaw.app`,请运行:
|
||||
|
||||
```bash
|
||||
./scripts/package-mac-app.sh
|
||||
```
|
||||
|
||||
如果你没有 Apple Developer ID 证书,脚本将自动使用**临时签名**(`-`)。
|
||||
|
||||
有关开发运行模式、签名选项和 Team ID 故障排除,请参阅 macOS 应用 README:
|
||||
https://github.com/openclaw/openclaw/blob/main/apps/macos/README.md
|
||||
|
||||
> **注意**:临时签名的应用可能会触发安全提示。如果应用立即崩溃并显示 "Abort trap 6",请参阅[故障排除](#troubleshooting)部分。
|
||||
|
||||
## 3. 安装 CLI
|
||||
|
||||
macOS 应用需要全局安装 `openclaw` CLI 来管理后台任务。
|
||||
|
||||
**安装方式(推荐):**
|
||||
|
||||
1. 打开 OpenClaw 应用。
|
||||
2. 进入 **General** 设置选项卡。
|
||||
3. 点击 **"Install CLI"**。
|
||||
|
||||
或者手动安装:
|
||||
|
||||
```bash
|
||||
npm install -g openclaw@<version>
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 构建失败:工具链或 SDK 不匹配
|
||||
|
||||
macOS 应用构建需要最新的 macOS SDK 和 Swift 6.2 工具链。
|
||||
|
||||
**系统依赖(必需):**
|
||||
|
||||
- **软件更新中可用的最新 macOS 版本**(Xcode 26.2 SDK 要求)
|
||||
- **Xcode 26.2**(Swift 6.2 工具链)
|
||||
|
||||
**检查:**
|
||||
|
||||
```bash
|
||||
xcodebuild -version
|
||||
xcrun swift --version
|
||||
```
|
||||
|
||||
如果版本不匹配,请更新 macOS/Xcode 并重新运行构建。
|
||||
|
||||
### 授权时应用崩溃
|
||||
|
||||
如果在尝试允许**语音识别**或**麦克风**访问时应用崩溃,可能是由于 TCC 缓存损坏或签名不匹配。
|
||||
|
||||
**修复方法:**
|
||||
|
||||
1. 重置 TCC 权限:
|
||||
```bash
|
||||
tccutil reset All bot.molt.mac.debug
|
||||
```
|
||||
2. 如果仍然无效,在 [`scripts/package-mac-app.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-app.sh) 中临时更改 `BUNDLE_ID`,以强制 macOS 使用"全新状态"。
|
||||
|
||||
### Gateway 持续显示"Starting..."
|
||||
|
||||
如果 Gateway 状态一直停留在"Starting...",请检查是否有僵尸进程占用了端口:
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
openclaw gateway stop
|
||||
|
||||
# 如果你没有使用 LaunchAgent(开发模式/手动运行),查找监听进程:
|
||||
lsof -nP -iTCP:18789 -sTCP:LISTEN
|
||||
```
|
||||
|
||||
如果是手动运行的进程占用了端口,请停止该进程(Ctrl+C)。作为最后手段,终止上面找到的 PID。
|
||||
41
docs/zh-CN/platforms/mac/health.md
Normal file
41
docs/zh-CN/platforms/mac/health.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
read_when:
|
||||
- 调试 Mac 应用健康指示器
|
||||
summary: macOS 应用如何报告 Gateway/Baileys 健康状态
|
||||
title: 健康检查
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:43Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 0560e96501ddf53a499f8960cfcf11c2622fcb9056bfd1bcc57876e955cab03d
|
||||
source_path: platforms/mac/health.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# macOS 上的健康检查
|
||||
|
||||
如何从菜单栏应用查看已关联渠道的健康状态。
|
||||
|
||||
## 菜单栏
|
||||
|
||||
- 状态圆点现在反映 Baileys 健康状态:
|
||||
- 绿色:已关联 + socket 近期已打开。
|
||||
- 橙色:正在连接/重试中。
|
||||
- 红色:已登出或探测失败。
|
||||
- 次要行显示 "linked · auth 12m" 或显示失败原因。
|
||||
- "运行健康检查" 菜单项可触发按需探测。
|
||||
|
||||
## 设置
|
||||
|
||||
- 通用选项卡新增健康卡片,显示:已关联认证时长、会话存储路径/数量、上次检查时间、上次错误/状态码,以及"运行健康检查"/"显示日志"按钮。
|
||||
- 使用缓存快照,使 UI 即时加载,离线时优雅降级。
|
||||
- **渠道选项卡**展示渠道状态 + WhatsApp/Telegram 的控制项(登录二维码、登出、探测、上次断连/错误)。
|
||||
|
||||
## 探测工作原理
|
||||
|
||||
- 应用每约 60 秒以及按需通过 `ShellExecutor` 运行 `openclaw health --json`。探测会加载凭据并报告状态,不会发送消息。
|
||||
- 分别缓存上次成功的快照和上次错误,以避免闪烁;显示各自的时间戳。
|
||||
|
||||
## 不确定时
|
||||
|
||||
- 您仍然可以使用 [Gateway 健康检查](/gateway/health) 中的 CLI 流程(`openclaw status`、`openclaw status --deep`、`openclaw health --json`),并跟踪 `/tmp/openclaw/openclaw-*.log` 中的 `web-heartbeat` / `web-reconnect`。
|
||||
38
docs/zh-CN/platforms/mac/icon.md
Normal file
38
docs/zh-CN/platforms/mac/icon.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
read_when:
|
||||
- 更改菜单栏图标行为
|
||||
summary: macOS 上 OpenClaw 菜单栏图标的状态和动画
|
||||
title: 菜单栏图标
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:49Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: a67a6e6bbdc2b611ba365d3be3dd83f9e24025d02366bc35ffcce9f0b121872b
|
||||
source_path: platforms/mac/icon.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 菜单栏图标状态
|
||||
|
||||
作者:steipete · 更新时间:2025-12-06 · 范围:macOS 应用(`apps/macos`)
|
||||
|
||||
- **空闲:** 正常图标动画(眨眼、偶尔摆动)。
|
||||
- **暂停:** 状态项使用 `appearsDisabled`;无动画。
|
||||
- **语音触发(大耳朵):** 语音唤醒检测器在听到唤醒词时调用 `AppState.triggerVoiceEars(ttl: nil)`,在捕获语音期间保持 `earBoostActive=true`。耳朵放大(1.9 倍),显示圆形耳孔以提高可读性,然后在 1 秒静音后通过 `stopVoiceEars()` 恢复。仅由应用内语音管道触发。
|
||||
- **工作中(智能体运行中):** `AppState.isWorking=true` 驱动"尾巴/腿部快速摆动"微动画:工作进行中腿部摆动加快并略有偏移。目前在 WebChat 智能体运行时切换;在接入其他长时间任务时请添加相同的切换逻辑。
|
||||
|
||||
接入点
|
||||
|
||||
- 语音唤醒:运行时/测试器在触发时调用 `AppState.triggerVoiceEars(ttl: nil)`,在 1 秒静音后调用 `stopVoiceEars()` 以匹配捕获窗口。
|
||||
- 智能体活动:在工作区间前后设置 `AppStateStore.shared.setWorking(true/false)`(已在 WebChat 智能体调用中完成)。保持区间简短,并在 `defer` 块中重置以避免动画卡住。
|
||||
|
||||
形状与尺寸
|
||||
|
||||
- 基础图标在 `CritterIconRenderer.makeIcon(blink:legWiggle:earWiggle:earScale:earHoles:)` 中绘制。
|
||||
- 耳朵缩放默认为 `1.0`;语音增强时设置 `earScale=1.9` 并切换 `earHoles=true`,不改变整体框架(18×18 pt 模板图像渲染到 36×36 px Retina 后备存储)。
|
||||
- 快速摆动使用最高约 1.0 的腿部摆幅并带有轻微的水平抖动;它与现有的空闲摆动叠加。
|
||||
|
||||
行为说明
|
||||
|
||||
- 耳朵/工作状态没有外部 CLI/代理切换;保持仅由应用自身信号控制,以避免意外的状态抖动。
|
||||
- 保持 TTL 较短(<10 秒),以便在任务挂起时图标能快速恢复到基准状态。
|
||||
64
docs/zh-CN/platforms/mac/logging.md
Normal file
64
docs/zh-CN/platforms/mac/logging.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
read_when:
|
||||
- 捕获 macOS 日志或调查隐私数据日志记录
|
||||
- 调试语音唤醒/会话生命周期问题
|
||||
summary: OpenClaw 日志:滚动诊断文件日志 + 统一日志隐私标志
|
||||
title: macOS 日志
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:54Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: c4c201d154915e0eb08bf5e32bac98fa93766f50f2a24bf56ab4424eb7781526
|
||||
source_path: platforms/mac/logging.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 日志(macOS)
|
||||
|
||||
## 滚动诊断文件日志(Debug 面板)
|
||||
|
||||
OpenClaw 通过 swift-log(默认使用统一日志)路由 macOS 应用日志,并且在需要持久化捕获时可以将本地轮转文件日志写入磁盘。
|
||||
|
||||
- 详细级别:**Debug 面板 → Logs → App logging → Verbosity**
|
||||
- 启用:**Debug 面板 → Logs → App logging → "Write rolling diagnostics log (JSONL)"**
|
||||
- 位置:`~/Library/Logs/OpenClaw/diagnostics.jsonl`(自动轮转;旧文件以 `.1`、`.2`、… 为后缀)
|
||||
- 清除:**Debug 面板 → Logs → App logging → "Clear"**
|
||||
|
||||
注意事项:
|
||||
|
||||
- 此功能**默认关闭**。仅在主动调试时启用。
|
||||
- 该文件包含敏感信息;分享前请先审查内容。
|
||||
|
||||
## macOS 上统一日志的隐私数据
|
||||
|
||||
统一日志会屏蔽大部分负载内容,除非子系统选择启用 `privacy -off`。根据 Peter 关于 macOS [日志隐私机制](https://steipete.me/posts/2025/logging-privacy-shenanigans)(2025)的文章,这通过 `/Library/Preferences/Logging/Subsystems/` 中以子系统名称为键的 plist 文件来控制。只有新的日志条目才会应用该标志,因此请在复现问题之前启用它。
|
||||
|
||||
## 为 OpenClaw 启用(`bot.molt`)
|
||||
|
||||
- 先将 plist 写入临时文件,然后以 root 身份原子性地安装:
|
||||
|
||||
```bash
|
||||
cat <<'EOF' >/tmp/bot.molt.plist
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>DEFAULT-OPTIONS</key>
|
||||
<dict>
|
||||
<key>Enable-Private-Data</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
sudo install -m 644 -o root -g wheel /tmp/bot.molt.plist /Library/Preferences/Logging/Subsystems/bot.molt.plist
|
||||
```
|
||||
|
||||
- 无需重启;logd 会很快检测到该文件,但只有新的日志行才会包含隐私负载。
|
||||
- 使用现有的辅助脚本查看更丰富的输出,例如 `./scripts/clawlog.sh --category WebChat --last 5m`。
|
||||
|
||||
## 调试后禁用
|
||||
|
||||
- 移除覆盖配置:`sudo rm /Library/Preferences/Logging/Subsystems/bot.molt.plist`。
|
||||
- 可选择运行 `sudo log config --reload` 强制 logd 立即丢弃覆盖配置。
|
||||
- 请注意此数据可能包含电话号码和消息正文;仅在确实需要额外详细信息时才保留该 plist 文件。
|
||||
88
docs/zh-CN/platforms/mac/menu-bar.md
Normal file
88
docs/zh-CN/platforms/mac/menu-bar.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
read_when:
|
||||
- 调整 Mac 菜单 UI 或状态逻辑
|
||||
summary: 菜单栏状态逻辑及向用户展示的内容
|
||||
title: 菜单栏
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:00Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 8eb73c0e671a76aae4ebb653c65147610bf3e6d3c9c0943d150e292e7761d16d
|
||||
source_path: platforms/mac/menu-bar.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 菜单栏状态逻辑
|
||||
|
||||
## 显示内容
|
||||
|
||||
- 我们在菜单栏图标和菜单的第一行状态行中展示当前智能体的工作状态。
|
||||
- 工作活跃时隐藏健康状态;当所有会话空闲时恢复显示。
|
||||
- 菜单中的"节点"区块仅列出**设备**(通过 `node.list` 配对的节点),不包括客户端/在线状态条目。
|
||||
- 当提供商用量快照可用时,"用量"部分会显示在上下文下方。
|
||||
|
||||
## 状态模型
|
||||
|
||||
- 会话:事件携带 `runId`(每次运行)以及载荷中的 `sessionKey`。"main" 会话的键为 `main`;如果不存在,则回退到最近更新的会话。
|
||||
- 优先级:main 始终优先。如果 main 处于活跃状态,立即显示其状态。如果 main 空闲,则显示最近活跃的非 main 会话。活动进行中不会来回切换;仅在当前会话进入空闲或 main 变为活跃时才切换。
|
||||
- 活动类型:
|
||||
- `job`:高层命令执行(`state: started|streaming|done|error`)。
|
||||
- `tool`:`phase: start|result`,包含 `toolName` 和 `meta/args`。
|
||||
|
||||
## IconState 枚举(Swift)
|
||||
|
||||
- `idle`
|
||||
- `workingMain(ActivityKind)`
|
||||
- `workingOther(ActivityKind)`
|
||||
- `overridden(ActivityKind)`(调试覆盖)
|
||||
|
||||
### ActivityKind → 图标符号
|
||||
|
||||
- `exec` → 💻
|
||||
- `read` → 📄
|
||||
- `write` → ✍️
|
||||
- `edit` → 📝
|
||||
- `attach` → 📎
|
||||
- 默认 → 🛠️
|
||||
|
||||
### 视觉映射
|
||||
|
||||
- `idle`:正常小动物图标。
|
||||
- `workingMain`:带图标符号的徽章,完整色调,腿部"工作"动画。
|
||||
- `workingOther`:带图标符号的徽章,柔和色调,无快跑动画。
|
||||
- `overridden`:无论活动状态如何,使用所选的图标符号/色调。
|
||||
|
||||
## 状态行文本(菜单)
|
||||
|
||||
- 工作活跃时:`<会话角色> · <活动标签>`
|
||||
- 示例:`Main · exec: pnpm test`、`Other · read: apps/macos/Sources/OpenClaw/AppState.swift`。
|
||||
- 空闲时:回退显示健康摘要。
|
||||
|
||||
## 事件接收
|
||||
|
||||
- 来源:控制渠道 `agent` 事件(`ControlChannel.handleAgentEvent`)。
|
||||
- 解析字段:
|
||||
- `stream: "job"`,包含 `data.state` 用于启动/停止。
|
||||
- `stream: "tool"`,包含 `data.phase`、`name`,可选 `meta`/`args`。
|
||||
- 标签:
|
||||
- `exec`:`args.command` 的第一行。
|
||||
- `read`/`write`:缩短的路径。
|
||||
- `edit`:路径加上从 `meta`/diff 计数推断的变更类型。
|
||||
- 回退:工具名称。
|
||||
|
||||
## 调试覆盖
|
||||
|
||||
- 设置 ▸ 调试 ▸ "图标覆盖" 选择器:
|
||||
- `系统(自动)`(默认)
|
||||
- `工作中:main`(按工具类型)
|
||||
- `工作中:other`(按工具类型)
|
||||
- `空闲`
|
||||
- 通过 `@AppStorage("iconOverride")` 存储;映射到 `IconState.overridden`。
|
||||
|
||||
## 测试清单
|
||||
|
||||
- 触发 main 会话任务:验证图标立即切换且状态行显示 main 标签。
|
||||
- main 空闲时触发非 main 会话任务:图标/状态显示非 main;保持稳定直到完成。
|
||||
- 在 other 活跃时启动 main:图标立即切换到 main。
|
||||
- 快速连续工具调用:确保徽章不会闪烁(工具结果的 TTL 宽限期)。
|
||||
- 所有会话空闲后健康行重新出现。
|
||||
62
docs/zh-CN/platforms/mac/peekaboo.md
Normal file
62
docs/zh-CN/platforms/mac/peekaboo.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
read_when:
|
||||
- 在 OpenClaw.app 中托管 PeekabooBridge
|
||||
- 通过 Swift Package Manager 集成 Peekaboo
|
||||
- 更改 PeekabooBridge 协议/路径
|
||||
summary: 用于 macOS UI 自动化的 PeekabooBridge 集成
|
||||
title: Peekaboo Bridge
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:57Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: b5b9ddb9a7c59e153a1d5d23c33616bb1542b5c7dadedc3af340aeee9ba03487
|
||||
source_path: platforms/mac/peekaboo.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Peekaboo Bridge(macOS UI 自动化)
|
||||
|
||||
OpenClaw 可以将 **PeekabooBridge** 作为本地的、权限感知的 UI 自动化代理进行托管。这使得 `peekaboo` CLI 能够驱动 UI 自动化,同时复用 macOS 应用的 TCC 权限。
|
||||
|
||||
## 这是什么(以及不是什么)
|
||||
|
||||
- **宿主**:OpenClaw.app 可以作为 PeekabooBridge 宿主。
|
||||
- **客户端**:使用 `peekaboo` CLI(无需单独的 `openclaw ui ...` 界面)。
|
||||
- **界面**:视觉叠加层保留在 Peekaboo.app 中;OpenClaw 只是一个轻量代理宿主。
|
||||
|
||||
## 启用桥接
|
||||
|
||||
在 macOS 应用中:
|
||||
|
||||
- 设置 → **启用 Peekaboo Bridge**
|
||||
|
||||
启用后,OpenClaw 会启动一个本地 UNIX 套接字服务器。如果禁用,宿主会停止,`peekaboo` 将回退到其他可用宿主。
|
||||
|
||||
## 客户端发现顺序
|
||||
|
||||
Peekaboo 客户端通常按以下顺序尝试宿主:
|
||||
|
||||
1. Peekaboo.app(完整用户体验)
|
||||
2. Claude.app(如已安装)
|
||||
3. OpenClaw.app(轻量代理)
|
||||
|
||||
使用 `peekaboo bridge status --verbose` 查看当前活跃的宿主及使用的套接字路径。你可以通过以下方式覆盖:
|
||||
|
||||
```bash
|
||||
export PEEKABOO_BRIDGE_SOCKET=/path/to/bridge.sock
|
||||
```
|
||||
|
||||
## 安全与权限
|
||||
|
||||
- 桥接会验证**调用方的代码签名**;强制执行 TeamID 白名单(Peekaboo 宿主 TeamID + OpenClaw 应用 TeamID)。
|
||||
- 请求在约 10 秒后超时。
|
||||
- 如果缺少所需权限,桥接会返回清晰的错误信息,而不是启动系统设置。
|
||||
|
||||
## 快照行为(自动化)
|
||||
|
||||
快照存储在内存中,并在短暂窗口期后自动过期。如果需要更长的保留时间,请从客户端重新捕获。
|
||||
|
||||
## 故障排除
|
||||
|
||||
- 如果 `peekaboo` 报告"bridge client is not authorized",请确保客户端已正确签名,或仅在**调试**模式下使用 `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` 运行宿主。
|
||||
- 如果未找到宿主,请打开其中一个宿主应用(Peekaboo.app 或 OpenClaw.app)并确认已授予权限。
|
||||
46
docs/zh-CN/platforms/mac/permissions.md
Normal file
46
docs/zh-CN/platforms/mac/permissions.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
read_when:
|
||||
- 调试缺失或卡住的 macOS 权限提示
|
||||
- 打包或签名 macOS 应用
|
||||
- 更改 Bundle ID 或应用安装路径
|
||||
summary: macOS 权限持久化(TCC)和签名要求
|
||||
title: macOS 权限
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:32:58Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: d012589c0583dd0b3792d695f3f71a6ff265704cf02a3b79f8c4a5b14712e6aa
|
||||
source_path: platforms/mac/permissions.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# macOS 权限(TCC)
|
||||
|
||||
macOS 权限授予是脆弱的。TCC 将权限授予与应用的代码签名、Bundle 标识符和磁盘路径关联。如果其中任何一项发生变化,macOS 会将该应用视为新应用,可能会丢弃或隐藏权限提示。
|
||||
|
||||
## 稳定权限的要求
|
||||
|
||||
- 相同路径:从固定位置运行应用(对于 OpenClaw,为 `dist/OpenClaw.app`)。
|
||||
- 相同 Bundle 标识符:更改 Bundle ID 会创建新的权限身份。
|
||||
- 已签名的应用:未签名或临时签名的构建不会持久化权限。
|
||||
- 一致的签名:使用真实的 Apple Development 或 Developer ID 证书,以确保签名在多次构建之间保持稳定。
|
||||
|
||||
临时签名每次构建都会生成新的身份。macOS 会忘记之前的授权,提示可能完全消失,直到清除过期条目为止。
|
||||
|
||||
## 权限提示消失时的恢复清单
|
||||
|
||||
1. 退出应用。
|
||||
2. 在系统设置 -> 隐私与安全性中移除该应用条目。
|
||||
3. 从相同路径重新启动应用并重新授予权限。
|
||||
4. 如果提示仍未出现,使用 `tccutil` 重置 TCC 条目后重试。
|
||||
5. 某些权限仅在完全重启 macOS 后才会重新出现。
|
||||
|
||||
重置示例(根据需要替换 Bundle ID):
|
||||
|
||||
```bash
|
||||
sudo tccutil reset Accessibility bot.molt.mac
|
||||
sudo tccutil reset ScreenCapture bot.molt.mac
|
||||
sudo tccutil reset AppleEvents
|
||||
```
|
||||
|
||||
如果你正在测试权限,请始终使用真实证书签名。临时签名的构建仅适用于不需要权限的快速本地运行。
|
||||
92
docs/zh-CN/platforms/mac/release.md
Normal file
92
docs/zh-CN/platforms/mac/release.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
read_when:
|
||||
- 制作或验证 OpenClaw macOS 发布版本
|
||||
- 更新 Sparkle appcast 或订阅源资源
|
||||
summary: OpenClaw macOS 发布清单(Sparkle 订阅源、打包、签名)
|
||||
title: macOS 发布
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:17Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 703c08c13793cd8c96bd4c31fb4904cdf4ffff35576e7ea48a362560d371cb30
|
||||
source_path: platforms/mac/release.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# OpenClaw macOS 发布(Sparkle)
|
||||
|
||||
本应用现已支持 Sparkle 自动更新。发布构建必须经过 Developer ID 签名、压缩,并发布包含签名的 appcast 条目。
|
||||
|
||||
## 前提条件
|
||||
|
||||
- 已安装 Developer ID Application 证书(示例:`Developer ID Application: <Developer Name> (<TEAMID>)`)。
|
||||
- 环境变量 `SPARKLE_PRIVATE_KEY_FILE` 已设置为 Sparkle ed25519 私钥路径(公钥已嵌入 Info.plist)。如果缺失,请检查 `~/.profile`。
|
||||
- 用于 `xcrun notarytool` 的公证凭据(钥匙串配置文件或 API 密钥),以实现通过 Gatekeeper 安全分发的 DMG/zip。
|
||||
- 我们使用名为 `openclaw-notary` 的钥匙串配置文件,由 shell 配置文件中的 App Store Connect API 密钥环境变量创建:
|
||||
- `APP_STORE_CONNECT_API_KEY_P8`、`APP_STORE_CONNECT_KEY_ID`、`APP_STORE_CONNECT_ISSUER_ID`
|
||||
- `echo "$APP_STORE_CONNECT_API_KEY_P8" | sed 's/\\n/\n/g' > /tmp/openclaw-notary.p8`
|
||||
- `xcrun notarytool store-credentials "openclaw-notary" --key /tmp/openclaw-notary.p8 --key-id "$APP_STORE_CONNECT_KEY_ID" --issuer "$APP_STORE_CONNECT_ISSUER_ID"`
|
||||
- 已安装 `pnpm` 依赖(`pnpm install --config.node-linker=hoisted`)。
|
||||
- Sparkle 工具通过 SwiftPM 自动获取,位于 `apps/macos/.build/artifacts/sparkle/Sparkle/bin/`(`sign_update`、`generate_appcast` 等)。
|
||||
|
||||
## 构建与打包
|
||||
|
||||
注意事项:
|
||||
|
||||
- `APP_BUILD` 映射到 `CFBundleVersion`/`sparkle:version`;保持纯数字且单调递增(不含 `-beta`),否则 Sparkle 会将其视为相同版本。
|
||||
- 默认为当前架构(`$(uname -m)`)。对于发布/通用构建,设置 `BUILD_ARCHS="arm64 x86_64"`(或 `BUILD_ARCHS=all`)。
|
||||
- 使用 `scripts/package-mac-dist.sh` 生成发布产物(zip + DMG + 公证)。使用 `scripts/package-mac-app.sh` 进行本地/开发打包。
|
||||
|
||||
```bash
|
||||
# 从仓库根目录运行;设置发布 ID 以启用 Sparkle 订阅源。
|
||||
# APP_BUILD 必须为纯数字且单调递增,以便 Sparkle 正确比较。
|
||||
BUNDLE_ID=bot.molt.mac \
|
||||
APP_VERSION=2026.1.27-beta.1 \
|
||||
APP_BUILD="$(git rev-list --count HEAD)" \
|
||||
BUILD_CONFIG=release \
|
||||
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
|
||||
scripts/package-mac-app.sh
|
||||
|
||||
# 打包用于分发的 zip(包含资源分支以支持 Sparkle 增量更新)
|
||||
ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.1.27-beta.1.zip
|
||||
|
||||
# 可选:同时构建适合用户使用的样式化 DMG(拖拽到 /Applications)
|
||||
scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.1.27-beta.1.dmg
|
||||
|
||||
# 推荐:构建 + 公证/装订 zip + DMG
|
||||
# 首先,创建一次钥匙串配置文件:
|
||||
# xcrun notarytool store-credentials "openclaw-notary" \
|
||||
# --apple-id "<apple-id>" --team-id "<team-id>" --password "<app-specific-password>"
|
||||
NOTARIZE=1 NOTARYTOOL_PROFILE=openclaw-notary \
|
||||
BUNDLE_ID=bot.molt.mac \
|
||||
APP_VERSION=2026.1.27-beta.1 \
|
||||
APP_BUILD="$(git rev-list --count HEAD)" \
|
||||
BUILD_CONFIG=release \
|
||||
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
|
||||
scripts/package-mac-dist.sh
|
||||
|
||||
# 可选:随发布一起提供 dSYM
|
||||
ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.1.27-beta.1.dSYM.zip
|
||||
```
|
||||
|
||||
## Appcast 条目
|
||||
|
||||
使用发布说明生成器,以便 Sparkle 渲染格式化的 HTML 说明:
|
||||
|
||||
```bash
|
||||
SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.1.27-beta.1.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
|
||||
```
|
||||
|
||||
从 `CHANGELOG.md`(通过 [`scripts/changelog-to-html.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/changelog-to-html.sh))生成 HTML 发布说明,并将其嵌入 appcast 条目。
|
||||
发布时,将更新后的 `appcast.xml` 与发布资源(zip + dSYM)一起提交。
|
||||
|
||||
## 发布与验证
|
||||
|
||||
- 将 `OpenClaw-2026.1.27-beta.1.zip`(和 `OpenClaw-2026.1.27-beta.1.dSYM.zip`)上传到标签 `v2026.1.27-beta.1` 对应的 GitHub 发布。
|
||||
- 确保原始 appcast URL 与内置的订阅源匹配:`https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml`。
|
||||
- 完整性检查:
|
||||
- `curl -I https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml` 返回 200。
|
||||
- `curl -I <enclosure url>` 在资源上传后返回 200。
|
||||
- 在之前的公开构建版本上,从 About 选项卡运行"Check for Updates…",验证 Sparkle 能正常安装新构建。
|
||||
|
||||
完成定义:已签名的应用 + appcast 已发布,从旧版本的更新流程正常工作,且发布资源已附加到 GitHub 发布。
|
||||
90
docs/zh-CN/platforms/mac/remote.md
Normal file
90
docs/zh-CN/platforms/mac/remote.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
read_when:
|
||||
- 设置或调试远程 Mac 控制
|
||||
summary: macOS 应用通过 SSH 远程控制 OpenClaw Gateway 的流程
|
||||
title: 远程控制
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:20Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 61b43707250d5515fd0f85f092bdde24598f14904398ff3fca3736bcc48d72f8
|
||||
source_path: platforms/mac/remote.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 远程 OpenClaw(macOS ⇄ 远程主机)
|
||||
|
||||
此流程让 macOS 应用充当运行在另一台主机(桌面/服务器)上的 OpenClaw Gateway 的完整远程控制器。这是应用的 **Remote over SSH**(远程运行)功能。所有功能——健康检查、语音唤醒转发和 Web Chat——都复用 _设置 → 通用_ 中相同的远程 SSH 配置。
|
||||
|
||||
## 模式
|
||||
|
||||
- **本地(此 Mac)**:所有内容在笔记本电脑上运行,无需 SSH。
|
||||
- **Remote over SSH(默认)**:OpenClaw 命令在远程主机上执行。Mac 应用使用 `-o BatchMode` 加上你选择的身份/密钥打开 SSH 连接,并进行本地端口转发。
|
||||
- **Remote direct (ws/wss)**:无 SSH 隧道。Mac 应用直接连接到 Gateway URL(例如通过 Tailscale Serve 或公共 HTTPS 反向代理)。
|
||||
|
||||
## 远程传输方式
|
||||
|
||||
远程模式支持两种传输方式:
|
||||
|
||||
- **SSH 隧道**(默认):使用 `ssh -N -L ...` 将 Gateway 端口转发到 localhost。由于隧道是回环的,Gateway 会将节点 IP 识别为 `127.0.0.1`。
|
||||
- **Direct (ws/wss)**:直接连接到 Gateway URL。Gateway 会看到真实的客户端 IP。
|
||||
|
||||
## 远程主机的前提条件
|
||||
|
||||
1. 安装 Node + pnpm 并构建/安装 OpenClaw CLI(`pnpm install && pnpm build && pnpm link --global`)。
|
||||
2. 确保 `openclaw` 在非交互式 shell 的 PATH 中(如有需要,创建符号链接到 `/usr/local/bin` 或 `/opt/homebrew/bin`)。
|
||||
3. 开启 SSH 密钥认证。我们建议使用 **Tailscale** IP 以实现局域网外的稳定可达性。
|
||||
|
||||
## macOS 应用设置
|
||||
|
||||
1. 打开 _设置 → 通用_。
|
||||
2. 在 **OpenClaw runs** 下,选择 **Remote over SSH** 并设置:
|
||||
- **传输方式**:**SSH 隧道** 或 **Direct (ws/wss)**。
|
||||
- **SSH 目标**:`user@host`(可选 `:port`)。
|
||||
- 如果 Gateway 在同一局域网中并通过 Bonjour 广播,可从发现列表中选择以自动填充此字段。
|
||||
- **Gateway URL**(仅 Direct 模式):`wss://gateway.example.ts.net`(或局域网使用 `ws://...`)。
|
||||
- **身份文件**(高级):密钥路径。
|
||||
- **项目根目录**(高级):用于命令执行的远程代码仓库路径。
|
||||
- **CLI 路径**(高级):可选的 `openclaw` 可执行入口/二进制文件路径(广播时自动填充)。
|
||||
3. 点击 **测试远程连接**。成功表示远程 `openclaw status --json` 正常运行。失败通常意味着 PATH/CLI 问题;exit 127 表示远程未找到 CLI。
|
||||
4. 健康检查和 Web Chat 现在会自动通过此 SSH 隧道运行。
|
||||
|
||||
## Web Chat
|
||||
|
||||
- **SSH 隧道**:Web Chat 通过转发的 WebSocket 控制端口(默认 18789)连接到 Gateway。
|
||||
- **Direct (ws/wss)**:Web Chat 直接连接到配置的 Gateway URL。
|
||||
- 不再有单独的 WebChat HTTP 服务器。
|
||||
|
||||
## 权限
|
||||
|
||||
- 远程主机需要与本地相同的 TCC 授权(自动化、辅助功能、屏幕录制、麦克风、语音识别、通知)。在该机器上运行上手引导以一次性授予权限。
|
||||
- 节点通过 `node.list` / `node.describe` 广播其权限状态,以便智能体了解可用功能。
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
- 建议在远程主机上绑定回环地址,并通过 SSH 或 Tailscale 连接。
|
||||
- 如果将 Gateway 绑定到非回环接口,请要求令牌/密码认证。
|
||||
- 参阅 [安全](/gateway/security) 和 [Tailscale](/gateway/tailscale)。
|
||||
|
||||
## WhatsApp 登录流程(远程)
|
||||
|
||||
- 在**远程主机**上运行 `openclaw channels login --verbose`。用手机上的 WhatsApp 扫描二维码。
|
||||
- 如果认证过期,在该主机上重新运行登录。健康检查会显示链接问题。
|
||||
|
||||
## 故障排除
|
||||
|
||||
- **exit 127 / not found**:`openclaw` 不在非登录 shell 的 PATH 中。将其添加到 `/etc/paths`、你的 shell rc 文件中,或创建符号链接到 `/usr/local/bin`/`/opt/homebrew/bin`。
|
||||
- **健康探测失败**:检查 SSH 可达性、PATH,以及 Baileys 是否已登录(`openclaw status --json`)。
|
||||
- **Web Chat 卡住**:确认 Gateway 在远程主机上正在运行,且转发端口与 Gateway WS 端口匹配;界面需要健康的 WS 连接。
|
||||
- **节点 IP 显示 127.0.0.1**:使用 SSH 隧道时这是预期行为。如果你希望 Gateway 看到真实客户端 IP,请将**传输方式**切换为 **Direct (ws/wss)**。
|
||||
- **语音唤醒**:触发短语在远程模式下会自动转发;无需单独的转发器。
|
||||
|
||||
## 通知声音
|
||||
|
||||
通过 `openclaw` 和 `node.invoke` 在脚本中为每个通知选择声音,例如:
|
||||
|
||||
```bash
|
||||
openclaw nodes notify --node <id> --title "Ping" --body "Remote gateway ready" --sound Glass
|
||||
```
|
||||
|
||||
应用中不再有全局"默认声音"开关;调用方按请求选择声音(或不使用声音)。
|
||||
54
docs/zh-CN/platforms/mac/signing.md
Normal file
54
docs/zh-CN/platforms/mac/signing.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
read_when:
|
||||
- 构建或签名 Mac 调试构建
|
||||
summary: 打包脚本生成的 macOS 调试构建的签名步骤
|
||||
title: macOS 签名
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:15Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 403b92f9a0ecdb7cb42ec097c684b7a696be3696d6eece747314a4dc90d8797e
|
||||
source_path: platforms/mac/signing.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Mac 签名(调试构建)
|
||||
|
||||
此应用通常从 [`scripts/package-mac-app.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-app.sh) 构建,该脚本目前会:
|
||||
|
||||
- 设置稳定的调试 Bundle 标识符:`ai.openclaw.mac.debug`
|
||||
- 使用该 Bundle ID 写入 Info.plist(可通过 `BUNDLE_ID=...` 覆盖)
|
||||
- 调用 [`scripts/codesign-mac-app.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/codesign-mac-app.sh) 对主二进制文件和应用包进行签名,使 macOS 将每次重新构建视为相同的已签名包,并保留 TCC 权限(通知、辅助功能、屏幕录制、麦克风、语音)。要获得稳定的权限,请使用真实签名身份;临时签名是可选的且不稳定(参阅 [macOS 权限](/platforms/mac/permissions))。
|
||||
- 默认使用 `CODESIGN_TIMESTAMP=auto`;为 Developer ID 签名启用受信任的时间戳。设置 `CODESIGN_TIMESTAMP=off` 可跳过时间戳(离线调试构建)。
|
||||
- 将构建元数据注入 Info.plist:`OpenClawBuildTimestamp`(UTC)和 `OpenClawGitCommit`(短哈希),以便"关于"面板可以显示构建信息、git 信息和调试/发布渠道。
|
||||
- **打包需要 Node 22+**:脚本会运行 TS 构建和 Control UI 构建。
|
||||
- 从环境变量中读取 `SIGN_IDENTITY`。将 `export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"`(或你的 Developer ID Application 证书)添加到 shell 配置文件中,以始终使用你的证书签名。临时签名需要通过 `ALLOW_ADHOC_SIGNING=1` 或 `SIGN_IDENTITY="-"` 显式启用(不建议用于权限测试)。
|
||||
- 签名后运行 Team ID 审计,如果应用包内的任何 Mach-O 文件由不同的 Team ID 签名则会失败。设置 `SKIP_TEAM_ID_CHECK=1` 可跳过此检查。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
# 从仓库根目录
|
||||
scripts/package-mac-app.sh # 自动选择身份;未找到时报错
|
||||
SIGN_IDENTITY="Developer ID Application: Your Name" scripts/package-mac-app.sh # 真实证书
|
||||
ALLOW_ADHOC_SIGNING=1 scripts/package-mac-app.sh # 临时签名(权限不会持久化)
|
||||
SIGN_IDENTITY="-" scripts/package-mac-app.sh # 显式临时签名(同样的限制)
|
||||
DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh # 仅限开发的 Sparkle Team ID 不匹配解决方案
|
||||
```
|
||||
|
||||
### 临时签名注意事项
|
||||
|
||||
使用 `SIGN_IDENTITY="-"`(临时签名)签名时,脚本会自动禁用**强化运行时**(`--options runtime`)。这是为了防止应用在尝试加载不共享相同 Team ID 的嵌入式框架(如 Sparkle)时崩溃。临时签名还会破坏 TCC 权限持久化;参阅 [macOS 权限](/platforms/mac/permissions) 了解恢复步骤。
|
||||
|
||||
## 关于面板的构建元数据
|
||||
|
||||
`package-mac-app.sh` 会在包中标记以下信息:
|
||||
|
||||
- `OpenClawBuildTimestamp`:打包时的 ISO8601 UTC 时间
|
||||
- `OpenClawGitCommit`:短 git 哈希(不可用时为 `unknown`)
|
||||
|
||||
"关于"选项卡读取这些键以显示版本、构建日期、git 提交以及是否为调试构建(通过 `#if DEBUG`)。代码更改后运行打包程序以刷新这些值。
|
||||
|
||||
## 原因
|
||||
|
||||
TCC 权限与 Bundle 标识符*和*代码签名绑定。使用不断变化的 UUID 的未签名调试构建会导致 macOS 在每次重新构建后忘记授权。对二进制文件进行签名(默认临时签名)并保持固定的 Bundle ID/路径(`dist/OpenClaw.app`)可以在构建之间保留授权,与 VibeTunnel 的方案一致。
|
||||
40
docs/zh-CN/platforms/mac/skills.md
Normal file
40
docs/zh-CN/platforms/mac/skills.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
read_when:
|
||||
- 更新 macOS 技能设置 UI
|
||||
- 更改技能门控或安装行为
|
||||
summary: macOS 技能设置 UI 及 Gateway 支持的状态
|
||||
title: 技能
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:07Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: ecd5286bbe49eed89319686c4f7d6da55ef7b0d3952656ba98ef5e769f3fbf79
|
||||
source_path: platforms/mac/skills.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 技能(macOS)
|
||||
|
||||
macOS 应用通过 Gateway 展示 OpenClaw 技能;不会在本地解析技能。
|
||||
|
||||
## 数据来源
|
||||
|
||||
- `skills.status`(Gateway)返回所有技能及其资格和缺失的依赖项
|
||||
(包括内置技能的白名单限制)。
|
||||
- 依赖项来源于每个 `SKILL.md` 中的 `metadata.openclaw.requires`。
|
||||
|
||||
## 安装操作
|
||||
|
||||
- `metadata.openclaw.install` 定义安装选项(brew/node/go/uv)。
|
||||
- 应用调用 `skills.install` 在 Gateway 主机上运行安装程序。
|
||||
- 当提供多个安装程序时,Gateway 仅展示一个首选安装程序
|
||||
(优先使用 brew,否则使用 `skills.install` 中的 node 管理器,默认为 npm)。
|
||||
|
||||
## 环境变量/API 密钥
|
||||
|
||||
- 应用将密钥存储在 `~/.openclaw/openclaw.json` 的 `skills.entries.<skillKey>` 下。
|
||||
- `skills.update` 可修改 `enabled`、`apiKey` 和 `env`。
|
||||
|
||||
## 远程模式
|
||||
|
||||
- 安装和配置更新在 Gateway 主机上执行(而非本地 Mac)。
|
||||
67
docs/zh-CN/platforms/mac/voice-overlay.md
Normal file
67
docs/zh-CN/platforms/mac/voice-overlay.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
read_when:
|
||||
- 调整语音浮层行为
|
||||
summary: 唤醒词与按键说话重叠时的语音浮层生命周期
|
||||
title: 语音浮层
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:26Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 3be1a60aa7940b2368ff62cd49f04b2b8422876030e8ea206b467f66a5a6bd4d
|
||||
source_path: platforms/mac/voice-overlay.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 语音浮层生命周期(macOS)
|
||||
|
||||
受众:macOS 应用贡献者。目标:在唤醒词与按键说话重叠时保持语音浮层行为可预测。
|
||||
|
||||
### 当前意图
|
||||
|
||||
- 如果浮层已因唤醒词显示,此时用户按下热键,热键会话会*接管*现有文本而非重置。浮层在热键按住期间保持显示。用户松开时:如果有去除空白后的文本则发送,否则关闭。
|
||||
- 单独使用唤醒词时仍在静音后自动发送;按键说话在松开时立即发送。
|
||||
|
||||
### 已实现(2025 年 12 月 9 日)
|
||||
|
||||
- 浮层会话现在为每次捕获(唤醒词或按键说话)携带一个令牌。当令牌不匹配时,部分/最终/发送/关闭/音量更新会被丢弃,避免过时回调。
|
||||
- 按键说话会接管任何可见的浮层文本作为前缀(因此在唤醒浮层显示时按下热键会保留文本并追加新语音)。它最多等待 1.5 秒获取最终转录结果,然后回退到当前文本。
|
||||
- 提示音/浮层日志以 `info` 级别输出,分类为 `voicewake.overlay`、`voicewake.ptt` 和 `voicewake.chime`(会话开始、部分、最终、发送、关闭、提示音原因)。
|
||||
|
||||
### 后续步骤
|
||||
|
||||
1. **VoiceSessionCoordinator(actor)**
|
||||
- 同一时间只拥有一个 `VoiceSession`。
|
||||
- API(基于令牌):`beginWakeCapture`、`beginPushToTalk`、`updatePartial`、`endCapture`、`cancel`、`applyCooldown`。
|
||||
- 丢弃携带过时令牌的回调(防止旧识别器重新打开浮层)。
|
||||
2. **VoiceSession(模型)**
|
||||
- 字段:`token`、`source`(wakeWord|pushToTalk)、已提交/临时文本、提示音标志、计时器(自动发送、空闲)、`overlayMode`(display|editing|sending)、冷却截止时间。
|
||||
3. **浮层绑定**
|
||||
- `VoiceSessionPublisher`(`ObservableObject`)将活跃会话镜像到 SwiftUI。
|
||||
- `VoiceWakeOverlayView` 仅通过 publisher 渲染;绝不直接修改全局单例。
|
||||
- 浮层用户操作(`sendNow`、`dismiss`、`edit`)携带会话令牌回调到 coordinator。
|
||||
4. **统一发送路径**
|
||||
- `endCapture` 时:如果去除空白后文本为空 → 关闭;否则 `performSend(session:)`(播放一次发送提示音、转发、关闭)。
|
||||
- 按键说话:无延迟;唤醒词:可选自动发送延迟。
|
||||
- 按键说话结束后对唤醒运行时施加短暂冷却,防止唤醒词立即重新触发。
|
||||
5. **日志**
|
||||
- Coordinator 在子系统 `bot.molt`、分类 `voicewake.overlay` 和 `voicewake.chime` 下输出 `.info` 级别日志。
|
||||
- 关键事件:`session_started`、`adopted_by_push_to_talk`、`partial`、`finalized`、`send`、`dismiss`、`cancel`、`cooldown`。
|
||||
|
||||
### 调试清单
|
||||
|
||||
- 复现浮层粘滞问题时流式查看日志:
|
||||
|
||||
```bash
|
||||
sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact
|
||||
```
|
||||
|
||||
- 验证只有一个活跃会话令牌;过时回调应被 coordinator 丢弃。
|
||||
- 确保按键说话松开时始终使用活跃令牌调用 `endCapture`;如果文本为空,预期 `dismiss` 且不播放提示音或发送。
|
||||
|
||||
### 迁移步骤(建议)
|
||||
|
||||
1. 添加 `VoiceSessionCoordinator`、`VoiceSession` 和 `VoiceSessionPublisher`。
|
||||
2. 重构 `VoiceWakeRuntime`,使其创建/更新/结束会话,而非直接操作 `VoiceWakeOverlayController`。
|
||||
3. 重构 `VoicePushToTalk`,使其接管现有会话并在松开时调用 `endCapture`;施加运行时冷却。
|
||||
4. 将 `VoiceWakeOverlayController` 连接到 publisher;移除来自 runtime/PTT 的直接调用。
|
||||
5. 添加会话接管、冷却和空文本关闭的集成测试。
|
||||
74
docs/zh-CN/platforms/mac/voicewake.md
Normal file
74
docs/zh-CN/platforms/mac/voicewake.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
read_when:
|
||||
- 正在开发语音唤醒或按键通话相关功能
|
||||
summary: Mac 应用中的语音唤醒和按键通话模式及路由详情
|
||||
title: 语音唤醒
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:32Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: f6440bb89f349ba5c1c9aacffe95e568681beb9899ca736dedfe2f4a366cb5e4
|
||||
source_path: platforms/mac/voicewake.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# 语音唤醒与按键通话
|
||||
|
||||
## 模式
|
||||
|
||||
- **唤醒词模式**(默认):常驻语音识别器等待触发词(`swabbleTriggerWords`)。匹配后开始采集,显示叠加层并展示部分文本,静默后自动发送。
|
||||
- **按键通话(长按右 Option 键)**:长按右 Option 键立即开始采集——无需触发词。长按期间显示叠加层;松开后完成采集并在短暂延迟后转发,以便您调整文本。
|
||||
|
||||
## 运行时行为(唤醒词)
|
||||
|
||||
- 语音识别器位于 `VoiceWakeRuntime` 中。
|
||||
- 仅当唤醒词和下一个词之间存在**有意义的停顿**(约 0.55 秒间隔)时才会触发。叠加层/提示音可以在停顿时启动,甚至在命令开始之前。
|
||||
- 静默窗口:语音持续时为 2.0 秒,仅听到触发词时为 5.0 秒。
|
||||
- 硬停止:120 秒,防止会话失控。
|
||||
- 会话间去抖:350 毫秒。
|
||||
- 叠加层通过 `VoiceWakeOverlayController` 驱动,具有已确认/临时着色。
|
||||
- 发送后,识别器干净重启以监听下一个触发词。
|
||||
|
||||
## 生命周期不变量
|
||||
|
||||
- 如果语音唤醒已启用且权限已授予,唤醒词识别器应保持监听状态(显式按键通话采集期间除外)。
|
||||
- 叠加层可见性(包括通过 X 按钮手动关闭)绝不能阻止识别器恢复。
|
||||
|
||||
## 叠加层卡住故障模式(历史问题)
|
||||
|
||||
此前,如果叠加层卡在可见状态并且您手动关闭它,语音唤醒可能表现为"无响应",因为运行时的重启尝试会被叠加层可见性阻塞,且不会调度后续重启。
|
||||
|
||||
加固措施:
|
||||
|
||||
- 唤醒运行时重启不再被叠加层可见性阻塞。
|
||||
- 叠加层关闭完成后通过 `VoiceSessionCoordinator` 触发 `VoiceWakeRuntime.refresh(...)`,因此手动点击 X 关闭始终会恢复监听。
|
||||
|
||||
## 按键通话详情
|
||||
|
||||
- 热键检测使用全局 `.flagsChanged` 监视器检测**右 Option 键**(`keyCode 61` + `.option`)。我们仅观察事件(不拦截)。
|
||||
- 采集管道位于 `VoicePushToTalk` 中:立即启动语音识别,将部分结果流式传输到叠加层,松开时调用 `VoiceWakeForwarder`。
|
||||
- 按键通话开始时,我们暂停唤醒词运行时以避免音频输入冲突;松开后自动重启。
|
||||
- 权限:需要麦克风 + 语音识别权限;查看事件需要辅助功能/输入监控授权。
|
||||
- 外接键盘:某些键盘可能无法按预期暴露右 Option 键——如果用户反馈未响应,请提供备用快捷键。
|
||||
|
||||
## 面向用户的设置
|
||||
|
||||
- **语音唤醒**开关:启用唤醒词运行时。
|
||||
- **长按 Cmd+Fn 说话**:启用按键通话监视器。在 macOS < 26 上禁用。
|
||||
- 语言和麦克风选择器、实时电平指示器、触发词表格、测试器(仅本地;不进行转发)。
|
||||
- 麦克风选择器在设备断开时保留上次选择,显示断开提示,并在设备恢复前临时回退到系统默认设备。
|
||||
- **声音**:触发检测和发送时播放提示音;默认使用 macOS "Glass" 系统声音。您可以为每个事件选择任何 `NSSound` 可加载的文件(如 MP3/WAV/AIFF),或选择**无声音**。
|
||||
|
||||
## 转发行为
|
||||
|
||||
- 启用语音唤醒后,转录文本将转发到活跃的 Gateway/智能体(与 Mac 应用其他部分使用的本地/远程模式相同)。
|
||||
- 回复将发送到**最近使用的主要提供商**(WhatsApp/Telegram/Discord/WebChat)。如果发送失败,错误会被记录,且运行仍可通过 WebChat/会话日志查看。
|
||||
|
||||
## 转发载荷
|
||||
|
||||
- `VoiceWakeForwarder.prefixedTranscript(_:)` 在发送前添加机器提示前缀。唤醒词和按键通话路径共用此逻辑。
|
||||
|
||||
## 快速验证
|
||||
|
||||
- 开启按键通话,长按 Cmd+Fn,说话,松开:叠加层应显示部分结果然后发送。
|
||||
- 长按期间,菜单栏耳朵图标应保持放大状态(使用 `triggerVoiceEars(ttl:nil)`);松开后恢复。
|
||||
43
docs/zh-CN/platforms/mac/webchat.md
Normal file
43
docs/zh-CN/platforms/mac/webchat.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
read_when:
|
||||
- 调试 Mac WebChat 视图或回环端口
|
||||
summary: Mac 应用如何嵌入 Gateway WebChat 以及如何调试
|
||||
title: WebChat
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:23Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: 04ff448758e530098e2004625f33e42fc3dbe31137cd3beec2d55590e507de08
|
||||
source_path: platforms/mac/webchat.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# WebChat(macOS 应用)
|
||||
|
||||
macOS 菜单栏应用将 WebChat UI 嵌入为原生 SwiftUI 视图。它连接到 Gateway,默认使用所选智能体的**主会话**(通过会话切换器可访问其他会话)。
|
||||
|
||||
- **本地模式**:直接连接到本地 Gateway WebSocket。
|
||||
- **远程模式**:通过 SSH 转发 Gateway 控制端口,并使用该隧道作为数据平面。
|
||||
|
||||
## 启动与调试
|
||||
|
||||
- 手动:Lobster 菜单 → "Open Chat"。
|
||||
- 测试时自动打开:
|
||||
```bash
|
||||
dist/OpenClaw.app/Contents/MacOS/OpenClaw --webchat
|
||||
```
|
||||
- 日志:`./scripts/clawlog.sh`(子系统 `bot.molt`,类别 `WebChatSwiftUI`)。
|
||||
|
||||
## 工作原理
|
||||
|
||||
- 数据平面:Gateway WS 方法 `chat.history`、`chat.send`、`chat.abort`、`chat.inject` 以及事件 `chat`、`agent`、`presence`、`tick`、`health`。
|
||||
- 会话:默认使用主会话(`main`,或作用域为全局时使用 `global`)。UI 可在会话之间切换。
|
||||
- 上手引导使用专用会话,以将首次运行设置与其他内容分开。
|
||||
|
||||
## 安全面
|
||||
|
||||
- 远程模式仅通过 SSH 转发 Gateway WebSocket 控制端口。
|
||||
|
||||
## 已知限制
|
||||
|
||||
- UI 针对聊天会话进行了优化(不是完整的浏览器沙箱)。
|
||||
68
docs/zh-CN/platforms/mac/xpc.md
Normal file
68
docs/zh-CN/platforms/mac/xpc.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
read_when:
|
||||
- 编辑 IPC 协议或菜单栏应用 IPC
|
||||
summary: OpenClaw 应用、gateway 节点传输和 PeekabooBridge 的 macOS IPC 架构
|
||||
title: macOS IPC
|
||||
x-i18n:
|
||||
generated_at: "2026-02-01T21:33:31Z"
|
||||
model: claude-opus-4-5
|
||||
provider: pi
|
||||
source_hash: d0211c334a4a59b71afb29dd7b024778172e529fa618985632d3d11d795ced92
|
||||
source_path: platforms/mac/xpc.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# OpenClaw macOS IPC 架构
|
||||
|
||||
**当前模型:** 本地 Unix 套接字将**节点宿主服务**连接到 **macOS 应用**,用于执行审批和 `system.run`。存在一个 `openclaw-mac` 调试 CLI 用于发现/连接检查;智能体操作仍通过 Gateway WebSocket 和 `node.invoke` 传递。UI 自动化使用 PeekabooBridge。
|
||||
|
||||
## 目标
|
||||
|
||||
- 单个 GUI 应用实例负责所有面向 TCC 的工作(通知、屏幕录制、麦克风、语音、AppleScript)。
|
||||
- 精简的自动化接口:Gateway + 节点命令,加上用于 UI 自动化的 PeekabooBridge。
|
||||
- 可预测的权限:始终使用相同的已签名 bundle ID,由 launchd 启动,确保 TCC 授权持久有效。
|
||||
|
||||
## 工作原理
|
||||
|
||||
### Gateway + 节点传输
|
||||
|
||||
- 应用运行 Gateway(本地模式)并作为节点连接到它。
|
||||
- 智能体操作通过 `node.invoke` 执行(例如 `system.run`、`system.notify`、`canvas.*`)。
|
||||
|
||||
### 节点服务 + 应用 IPC
|
||||
|
||||
- 无界面的节点宿主服务通过 WebSocket 连接到 Gateway。
|
||||
- `system.run` 请求通过本地 Unix 套接字转发到 macOS 应用。
|
||||
- 应用在 UI 上下文中执行操作,必要时提示用户确认,并返回输出。
|
||||
|
||||
架构图(SCI):
|
||||
|
||||
```
|
||||
Agent -> Gateway -> Node Service (WS)
|
||||
| IPC (UDS + token + HMAC + TTL)
|
||||
v
|
||||
Mac App (UI + TCC + system.run)
|
||||
```
|
||||
|
||||
### PeekabooBridge(UI 自动化)
|
||||
|
||||
- UI 自动化使用名为 `bridge.sock` 的独立 UNIX 套接字和 PeekabooBridge JSON 协议。
|
||||
- 宿主优先级顺序(客户端侧):Peekaboo.app → Claude.app → OpenClaw.app → 本地执行。
|
||||
- 安全性:bridge 宿主要求允许的 TeamID;仅 DEBUG 模式下的同 UID 回退机制受 `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1`(Peekaboo 约定)保护。
|
||||
- 详见:[PeekabooBridge 用法](/platforms/mac/peekaboo)。
|
||||
|
||||
## 操作流程
|
||||
|
||||
- 重启/重新构建:`SIGN_IDENTITY="Apple Development: <Developer Name> (<TEAMID>)" scripts/restart-mac.sh`
|
||||
- 终止现有实例
|
||||
- Swift 构建 + 打包
|
||||
- 写入/引导/启动 LaunchAgent
|
||||
- 单实例:如果另一个具有相同 bundle ID 的实例正在运行,应用会提前退出。
|
||||
|
||||
## 安全加固说明
|
||||
|
||||
- 优先要求所有特权接口进行 TeamID 匹配。
|
||||
- PeekabooBridge:`PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1`(仅 DEBUG 模式)可允许同 UID 调用方用于本地开发。
|
||||
- 所有通信仅限本地;不暴露网络套接字。
|
||||
- TCC 提示仅来自 GUI 应用 bundle;跨重新构建时保持已签名的 bundle ID 稳定。
|
||||
- IPC 加固:套接字模式 `0600`、令牌、对端 UID 检查、HMAC 质询/响应、短 TTL。
|
||||
Reference in New Issue
Block a user