Merge remote-tracking branch 'origin/feature/computer-use/mac-support'

This commit is contained in:
claude-code-best
2026-04-04 16:42:51 +08:00
10 changed files with 578 additions and 394 deletions

View File

@@ -51,8 +51,8 @@ bun run docs:dev
### Runtime & Build ### Runtime & Build
- **Runtime**: Bun (not Node.js). All imports, builds, and execution use Bun APIs. - **Runtime**: Bun (not Node.js). All imports, builds, and execution use Bun APIs.
- **Build**: `build.ts` 执行 `Bun.build()` with `splitting: true`,入口 `src/entrypoints/cli.tsx`,输出 `dist/cli.js` + chunk files。默认启用 `AGENT_TRIGGERS_REMOTE` feature。构建后自动替换 `import.meta.require` 为 Node.js 兼容版本(产物 bun/node 都可运行)。 - **Build**: `build.ts` 执行 `Bun.build()` with `splitting: true`,入口 `src/entrypoints/cli.tsx`,输出 `dist/cli.js` + chunk files。默认启用 `AGENT_TRIGGERS_REMOTE``CHICAGO_MCP``VOICE_MODE` feature。构建后自动替换 `import.meta.require` 为 Node.js 兼容版本(产物 bun/node 都可运行)。
- **Dev mode**: `scripts/dev.ts` 通过 Bun `-d` flag 注入 `MACRO.*` defines运行 `src/entrypoints/cli.tsx`。默认启用 `BUDDY``TRANSCRIPT_CLASSIFIER``BRIDGE_MODE``AGENT_TRIGGERS_REMOTE`个 feature。 - **Dev mode**: `scripts/dev.ts` 通过 Bun `-d` flag 注入 `MACRO.*` defines运行 `src/entrypoints/cli.tsx`。默认启用 `BUDDY``TRANSCRIPT_CLASSIFIER``BRIDGE_MODE``AGENT_TRIGGERS_REMOTE``CHICAGO_MCP``VOICE_MODE`个 feature。
- **Module system**: ESM (`"type": "module"`), TSX with `react-jsx` transform. - **Module system**: ESM (`"type": "module"`), TSX with `react-jsx` transform.
- **Monorepo**: Bun workspaces — internal packages live in `packages/` resolved via `workspace:*`. - **Monorepo**: Bun workspaces — internal packages live in `packages/` resolved via `workspace:*`.
- **Lint/Format**: Biome (`biome.json`)。`bun run lint` / `bun run lint:fix` / `bun run format` - **Lint/Format**: Biome (`biome.json`)。`bun run lint` / `bun run lint:fix` / `bun run format`
@@ -132,8 +132,8 @@ Feature flags control which functionality is enabled at runtime:
- **在代码中使用**: 统一通过 `import { feature } from 'bun:bundle'` 导入,调用 `feature('FLAG_NAME')` 返回 `boolean`。**不要**在 `cli.tsx` 或其他文件里自己定义 `feature` 函数或覆盖这个 import。 - **在代码中使用**: 统一通过 `import { feature } from 'bun:bundle'` 导入,调用 `feature('FLAG_NAME')` 返回 `boolean`。**不要**在 `cli.tsx` 或其他文件里自己定义 `feature` 函数或覆盖这个 import。
- **启用方式**: 通过环境变量 `FEATURE_<FLAG_NAME>=1`。例如 `FEATURE_BUDDY=1 bun run dev` 启用 BUDDY 功能。 - **启用方式**: 通过环境变量 `FEATURE_<FLAG_NAME>=1`。例如 `FEATURE_BUDDY=1 bun run dev` 启用 BUDDY 功能。
- **Dev 默认 features**: `BUDDY``TRANSCRIPT_CLASSIFIER``BRIDGE_MODE``AGENT_TRIGGERS_REMOTE`(见 `scripts/dev.ts`)。 - **Dev 默认 features**: `BUDDY``TRANSCRIPT_CLASSIFIER``BRIDGE_MODE``AGENT_TRIGGERS_REMOTE``CHICAGO_MCP``VOICE_MODE`(见 `scripts/dev.ts`)。
- **Build 默认 features**: `AGENT_TRIGGERS_REMOTE`(见 `build.ts`)。 - **Build 默认 features**: `AGENT_TRIGGERS_REMOTE``CHICAGO_MCP``VOICE_MODE`(见 `build.ts`)。
- **常见 flag**: `BUDDY`, `DAEMON`, `BRIDGE_MODE`, `BG_SESSIONS`, `PROACTIVE`, `KAIROS`, `VOICE_MODE`, `FORK_SUBAGENT`, `SSH_REMOTE`, `DIRECT_CONNECT`, `TEMPLATES`, `CHICAGO_MCP`, `BYOC_ENVIRONMENT_RUNNER`, `SELF_HOSTED_RUNNER`, `COORDINATOR_MODE`, `UDS_INBOX`, `LODESTONE`, `ABLATION_BASELINE` 等。 - **常见 flag**: `BUDDY`, `DAEMON`, `BRIDGE_MODE`, `BG_SESSIONS`, `PROACTIVE`, `KAIROS`, `VOICE_MODE`, `FORK_SUBAGENT`, `SSH_REMOTE`, `DIRECT_CONNECT`, `TEMPLATES`, `CHICAGO_MCP`, `BYOC_ENVIRONMENT_RUNNER`, `SELF_HOSTED_RUNNER`, `COORDINATOR_MODE`, `UDS_INBOX`, `LODESTONE`, `ABLATION_BASELINE` 等。
- **类型声明**: `src/types/internal-modules.d.ts` 中声明了 `bun:bundle` 模块的 `feature` 函数签名。 - **类型声明**: `src/types/internal-modules.d.ts` 中声明了 `bun:bundle` 模块的 `feature` 函数签名。
@@ -143,13 +143,45 @@ Feature flags control which functionality is enabled at runtime:
| Module | Status | | Module | Status |
|--------|--------| |--------|--------|
| Computer Use (`@ant/*`) | Stub packages in `packages/@ant/` | | Computer Use (`@ant/*`) | Restored — `computer-use-swift`, `computer-use-input`, `computer-use-mcp`, `claude-for-chrome-mcp` 均有完整实现macOS + Windows 可用Linux 后端待完成 |
| `*-napi` packages (audio, image, url, modifiers) | Stubs in `packages/` (except `color-diff-napi` which is fully implemented) | | `*-napi` packages | `audio-capture-napi``image-processor-napi` 已恢复实现;`color-diff-napi` 完整实现;`url-handler-napi``modifiers-napi` 仍为 stub |
| Voice Mode | Restored — `src/voice/``src/hooks/useVoiceIntegration.tsx``src/services/voiceStreamSTT.ts`Push-to-Talk 语音输入(需 Anthropic OAuth |
| OpenAI 兼容层 | Restored — `src/services/api/openai/`,支持 Ollama/DeepSeek/vLLM 等任意 OpenAI 协议端点,通过 `CLAUDE_CODE_USE_OPENAI=1` 启用 |
| Analytics / GrowthBook / Sentry | Empty implementations | | Analytics / GrowthBook / Sentry | Empty implementations |
| Magic Docs / Voice Mode / LSP Server | Removed | | Magic Docs / LSP Server | Removed |
| Plugins / Marketplace | Removed | | Plugins / Marketplace | Removed |
| MCP OAuth | Simplified | | MCP OAuth | Simplified |
### Computer Use
Feature flag `CHICAGO_MCP`dev/build 默认启用。实现跨平台屏幕操控macOS + Windows 可用Linux 待完成)。
- **`packages/@ant/computer-use-mcp/`** — MCP server注册截图/键鼠/剪贴板/应用管理工具
- **`packages/@ant/computer-use-input/`** — 键鼠模拟dispatcher + per-platform backend`backends/darwin.ts``win32.ts``linux.ts`
- **`packages/@ant/computer-use-swift/`** — 截图 + 应用管理,同样 dispatcher + per-platform backend
- **`packages/@ant/claude-for-chrome-mcp/`** — Chrome 浏览器控制(独立于 Computer Use通过 `--chrome` CLI 参数启用)
详见 `docs/features/computer-use.md`
### Voice Mode
Feature flag `VOICE_MODE`dev/build 默认启用。Push-to-Talk 语音输入,音频通过 WebSocket 流式传输到 Anthropic STTNova 3。需要 Anthropic OAuth非 API key
- **`src/voice/voiceModeEnabled.ts`** — 三层门控feature flag + GrowthBook + OAuth auth
- **`src/hooks/useVoice.ts`** — React hook 管理录音状态和 WebSocket 连接
- **`src/services/voiceStreamSTT.ts`** — STT WebSocket 流式传输
详见 `docs/features/voice-mode.md`
### OpenAI 兼容层
通过 `CLAUDE_CODE_USE_OPENAI=1` 环境变量启用,支持任意 OpenAI Chat Completions 协议端点Ollama、DeepSeek、vLLM 等)。流适配器模式:在 `queryModel()` 中将 Anthropic 格式请求转为 OpenAI 格式,再将 SSE 流转换回 `BetaRawMessageStreamEvent`,下游代码完全不改。
- **`src/services/api/openai/`** — client、消息/工具转换、流适配、模型映射
- **`src/utils/model/providers.ts`** — 添加 `'openai'` provider 类型(最高优先级)
关键环境变量:`CLAUDE_CODE_USE_OPENAI``OPENAI_API_KEY``OPENAI_BASE_URL``OPENAI_MODEL``OPENAI_MODEL_MAP`。详见 `docs/plans/openai-compatibility.md`
### Key Type Files ### Key Type Files
- **`src/types/global.d.ts`** — Declares `MACRO`, `BUILD_TARGET`, `BUILD_ENV` and internal Anthropic-only identifiers. - **`src/types/global.d.ts`** — Declares `MACRO`, `BUILD_TARGET`, `BUILD_ENV` and internal Anthropic-only identifiers.

View File

@@ -25,6 +25,18 @@
--- ---
## Computer Use macOS 适配修复 (2026-04-04)
**分支**: `feature/computer-use/mac-support`
- **darwin.ts** — 应用枚举改用 Spotlight `mdfind` + `mdls`,获取真实 bundleId旧方案合成 `com.app.xxx`),覆盖 `/Applications` + `/System/Applications` + CoreServices
- **index.ts** — 新增 `hotkey` backend fallback非原生模块不崩溃
- **toolCalls.ts** — `resolveRequestedApps()` 新增子串模糊匹配(`"Chrome"``"Google Chrome"`
- **hostAdapter.ts** — `ensureOsPermissions()` 检查 `cu.tcc` 存在性,跨平台 JS backend 安全降级
- **测试**: 17 个 MCP 工具中 10 个完全通过6 个在 full tier 应用上通过IDE click tier 受限为预期行为),`screenshot` 未返回图片(疑似屏幕录制权限问题)
---
## Computer Use Windows 增强:窗口绑定截图 + UI Automation + OCR (2026-04-03) ## Computer Use Windows 增强:窗口绑定截图 + UI Automation + OCR (2026-04-03)
在三平台基础实现之上,利用 Windows 原生 API 增强 Computer Use 的 Windows 专属能力。 在三平台基础实现之上,利用 Windows 原生 API 增强 Computer Use 的 Windows 专属能力。

View File

@@ -34,17 +34,18 @@
- [x] 关闭自动更新; - [x] 关闭自动更新;
- [x] 添加自定义 sentry 错误上报支持 [文档](https://ccb.agent-aura.top/docs/internals/sentry-setup) - [x] 添加自定义 sentry 错误上报支持 [文档](https://ccb.agent-aura.top/docs/internals/sentry-setup)
- [x] 添加自定义 GrowthBook 支持 (GB 也是开源的, 现在你可以配置一个自定义的遥控平台) [文档](https://ccb.agent-aura.top/docs/internals/growthbook-adapter) - [x] 添加自定义 GrowthBook 支持 (GB 也是开源的, 现在你可以配置一个自定义的遥控平台) [文档](https://ccb.agent-aura.top/docs/internals/growthbook-adapter)
- [x] 自定义 login 模式, 大家可以用这个配置 Claude 的模型! - [x] 自定义 login 模式, 大家可以用这个配置 Claude 的模型! [文档](https://ccb.agent-aura.top/docs/features/custom-platform-login)
- [x] Remote Control / Bridge Mode 支持 [文档](https://ccb.agent-aura.top/docs/features/bridge-mode)
- [x] 修复搜索工具的 rg 缺失问题(需要重新 bun i) - [x] 修复搜索工具的 rg 缺失问题(需要重新 bun i)
- [x] OpenAI 接口兼容! /login 然后配置 OpenAI 平台即可! - [x] OpenAI 接口兼容! /login 然后配置 OpenAI 平台即可! [文档](https://ccb.agent-aura.top/docs/plans/openai-compatibility)
- [x] Any Use - [x] Any Use
- [x] 由于 Chrome Use 和 Computer Use 原本都是未完全验证的能力, 还是比较建议大家用社区里面的 MCP 支持 - [x] 由于 Chrome Use 和 Computer Use 原本都是未完全验证的能力, 还是比较建议大家用社区里面的 MCP 支持
- [x] Chrome use 支持 (浏览器插件要订阅权限 ) 感谢 @amDosion - [x] Chrome use 支持 (浏览器插件要订阅权限 ) 感谢 @amDosion [文档](https://ccb.agent-aura.top/docs/features/claude-in-chrome-mcp)
- [x] 普通用户可以使用 [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp/) 替代, 比较不那么折腾 - [x] 普通用户可以使用 [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp/) 替代, 比较不那么折腾
- [x] Computer use 支持 感谢 @amDosion - [x] Computer use 支持 感谢 @amDosion [文档](https://ccb.agent-aura.top/docs/features/computer-use)
- [x] Mac 上可以用这个项目 [computer-use-mcp](https://github.com/domdomegg/computer-use-mcp) - [x] Mac 上可以用这个项目 [computer-use-mcp](https://github.com/domdomegg/computer-use-mcp)
- 注意这个库的命名方式与官方冲突了, 需要改为 `claude mcp add --scope user --transport stdio computer-use-mcp -- npx -y computer-use-mcp` - 注意这个库的命名方式与官方冲突了, 需要改为 `claude mcp add --scope user --transport stdio computer-use-mcp -- npx -y computer-use-mcp`
- [x] /voice 支持 @amDosion - [x] /voice 支持 @amDosion [文档](https://ccb.agent-aura.top/docs/features/voice-mode)
- [x] /dream 记忆整理命令(手动 + 自动后台触发) [文档](https://ccb.agent-aura.top/docs/features/auto-dream) - [x] /dream 记忆整理命令(手动 + 自动后台触发) [文档](https://ccb.agent-aura.top/docs/features/auto-dream)
- [ ] V6 大规模重构石山代码, 全面模块分包 - [ ] V6 大规模重构石山代码, 全面模块分包
- [ ] V6 将会为全新分支, 届时 main 分支将会封存为历史版本 - [ ] V6 将会为全新分支, 届时 main 分支将会封存为历史版本

View File

@@ -1,243 +1,137 @@
# Claude in Chrome MCP — 恢复计划 # Claude in Chrome — 用户操作指南
更新时间2026-04-03 ## 1. 功能简介
参考项目:`E:\源码\claude-code-source-main\claude-code-source-main`
## 1. 功能概述 Claude in Chrome 让 Claude Code 直接控制你的 Chrome 浏览器。你可以用自然语言让 Claude 帮你:
Claude in Chrome 让 Claude Code CLI 通过 MCP 协议控制用户的 Chrome 浏览器:导航网页、填写表单、截图、录制 GIF、读取 DOM、执行 JS、监控网络请求和控制台日志。 - 打开网页、导航、前进后退
- 填写表单、上传图片
- 截图、录制 GIF
- 读取页面内容DOM、纯文本
- 执行 JavaScript
- 监控网络请求和控制台日志
- 管理标签页
通信方式有两种: ## 2. 前置条件
- **本地 Socket**Chrome 扩展通过 Native Messaging Host 与 CLI 建立 Unix socket 连接
- **Bridge WebSocket**:通过 Anthropic 的 bridge 服务中转,支持远程浏览器
## 2. 完整加载链路 | 条件 | 说明 |
|------|------|
| Claude Code 订阅 | 需要 Claude Pro、Max 或 Team 订阅,浏览器插件功能不向免费用户开放 |
| Chrome 浏览器 | 需已安装 Google Chrome |
| Claude in Chrome 扩展 | 从 Chrome Web Store 安装(`claude.ai/chrome` |
| Claude Code CLI | 已通过 `bun run dev` 或构建产物运行 |
``` ## 3. 启用方式
CLI 启动
### Dev 模式
src/main.tsx:1003 ```bash
.option('--chrome', 'Enable Claude in Chrome integration') bun run dev -- --chrome
src/main.tsx:1522-1527
setChromeFlagOverride(chromeOpts.chrome)
src/utils/claudeInChrome/setup.ts
shouldEnableClaudeInChrome()
├── --chrome flag → true
├── --no-chrome flag → false
├── 非交互模式 → false
├── 环境变量 CLAUDE_CODE_DISABLE_CHROME → false
├── 配置 claudeInChromeDefaultEnabled → true/false
└── Chrome 扩展已安装 + GrowthBook tengu_chrome_auto_enable → auto
src/utils/claudeInChrome/setup.ts
setupClaudeInChrome()
├── 生成 MCP server 配置
└── 返回 mcpConfig + allowedTools
src/utils/claudeInChrome/mcpServer.ts
import { createClaudeForChromeMcpServer } from '@ant/claude-for-chrome-mcp'
packages/@ant/claude-for-chrome-mcp/src/index.ts ← 当前是 STUB
export function createClaudeForChromeMcpServer() { return null }
export const BROWSER_TOOLS = []
``` ```
## 3. 阻塞点清单 启动后 Claude 会自动检测 Chrome 扩展是否已安装,并注册浏览器控制工具。
| # | 阻塞点 | 位置 | 状态 | ### 构建产物
|---|--------|------|------|
| ① | `@ant/claude-for-chrome-mcp` 是 stub | `packages/@ant/claude-for-chrome-mcp/src/index.ts` | **6 行空壳,返回 null** |
| ② | 缺少完整实现7 个文件3038 行) | `packages/@ant/claude-for-chrome-mcp/src/` | 只有 1 个 stub 文件 |
**不需要任何 feature flag**`/chrome` 命令无条件注册在 `src/commands.ts:264` ```bash
node dist/cli.js --chrome
```
**不需要改 `src/` 下任何文件** — 以下文件全部与参考项目 0 行差异: ### 禁用
- `src/utils/claudeInChrome/setup.ts`
- `src/utils/claudeInChrome/mcpServer.ts`
- `src/utils/claudeInChrome/common.ts`
- `src/utils/claudeInChrome/chromeNativeHost.ts`
- `src/utils/claudeInChrome/prompt.ts`
- `src/utils/claudeInChrome/setupPortable.ts`
- `src/utils/claudeInChrome/toolRendering.tsx`
- `src/commands/chrome/index.ts`
- `src/commands/chrome/chrome.tsx`(仅 sourcemap 差异)
- `src/skills/bundled/claudeInChrome.ts`
## 4. 参考项目完整实现清单 ```bash
bun run dev -- --no-chrome
```
参考项目路径:`deps/@ant/claude-for-chrome-mcp/src/` 或在 REPL 中通过 `/chrome` 命令切换启用/禁用状态。
| 文件 | 行数 | 职责 | ### 通过配置默认启用
|------|------|------|
| `index.ts` | 15 | 导出入口:`createBridgeClient``BROWSER_TOOLS``createChromeSocketClient``createClaudeForChromeMcpServer``localPlatformLabel` + 类型导出 |
| `types.ts` | 134 | 类型定义:`Logger``PermissionMode``BridgeConfig``ChromeExtensionInfo``ClaudeForChromeContext``SocketClient``BridgePermissionRequest/Response``PermissionOverrides` |
| `browserTools.ts` | 546 | 17 个浏览器工具定义MCP tool schema |
| `mcpServer.ts` | 96 | MCP Server 创建:注册 `ListTools`/`CallTool` handler选择 socket/bridge 传输 |
| `mcpSocketClient.ts` | 493 | Unix Socket 客户端:连接 Chrome Native Messaging HostJSON-RPC 通信 |
| `mcpSocketPool.ts` | 327 | Socket 连接池:多 Chrome profile 支持,按 tabId 路由 |
| `bridgeClient.ts` | 1126 | Bridge WebSocket 客户端:连接 Anthropic bridge 服务,扩展发现、设备配对、权限管理 |
| `toolCalls.ts` | 301 | 工具调用路由:连接状态处理、结果转换、权限模式切换、浏览器切换 |
### 17 个浏览器工具 在 Claude Code 设置中将 `claudeInChromeDefaultEnabled` 设为 `true`,以后启动无需加 `--chrome` 参数。
| 工具名 | 功能 | ## 4. 使用流程
|--------|------|
| `javascript_tool` | 在页面上下文执行 JavaScript | 1. **启动 CLI** — 加 `--chrome` 参数启动 Claude Code
| `read_page` | 获取页面可访问性树DOM | 2. **确认连接** — REPL 中输入 `/chrome`,查看扩展状态是否显示 "Installed / Connected"
| `find` | 自然语言搜索页面元素 | 3. **开始对话** — 正常与 Claude 对话,当需要操作浏览器时直接说,例如:
- "打开 https://example.com 并截图"
- "在当前页面搜索关键词 xxx"
- "填写登录表单,用户名 admin"
- "帮我录制当前操作的 GIF"
4. **权限审批** — 首次执行浏览器操作时Claude 会请求你的确认
5. **操作完成** — Claude 完成操作后会返回结果(截图、文本、执行结果等)
## 5. 可用操作
### 页面交互
| 操作 | 说明 |
|------|------|
| `navigate` | 导航到指定 URL或前进/后退 |
| `computer` | 鼠标点击、移动、拖拽、键盘输入、截图等13 种 action |
| `form_input` | 填写表单字段 | | `form_input` | 填写表单字段 |
| `computer` | 鼠标键盘操作 + 截图13 种 action | | `upload_image` | 上传图片到文件输入框或拖拽区域 |
| `navigate` | URL 导航 / 前进后退 | | `javascript_tool` | 在页面上下文执行 JavaScript |
| `resize_window` | 调整浏览器窗口尺寸 |
| `gif_creator` | GIF 录制和导出 | ### 页面读取
| `upload_image` | 图片上传到文件输入框或拖拽区域 |
| `get_page_text` | 提取页面纯文本 | | 操作 | 说明 |
|------|------|
| `read_page` | 获取页面可访问性树DOM 结构) |
| `get_page_text` | 提取页面纯文本内容 |
| `find` | 用自然语言搜索页面元素 |
### 标签页管理
| 操作 | 说明 |
|------|------|
| `tabs_context_mcp` | 获取当前标签组信息 | | `tabs_context_mcp` | 获取当前标签组信息 |
| `tabs_create_mcp` | 创建新标签页 | | `tabs_create_mcp` | 创建新标签页 |
| `update_plan` | 向用户提交操作计划供审批 |
### 监控与调试
| 操作 | 说明 |
|------|------|
| `read_console_messages` | 读取浏览器控制台日志 | | `read_console_messages` | 读取浏览器控制台日志 |
| `read_network_requests` | 读取网络请求 | | `read_network_requests` | 读取网络请求记录 |
### 其他
| 操作 | 说明 |
|------|------|
| `resize_window` | 调整浏览器窗口尺寸 |
| `gif_creator` | 录制 GIF 并导出 |
| `shortcuts_list` | 列出可用快捷方式 | | `shortcuts_list` | 列出可用快捷方式 |
| `shortcuts_execute` | 执行快捷方式 | | `shortcuts_execute` | 执行快捷方式 |
| `switch_browser` | 切换到其他 Chrome 浏览器(仅 bridge 模式) | | `update_plan` | 向你提交操作计划供审批 |
| `switch_browser` | 切换到其他 Chrome 浏览器(仅 Bridge 模式) |
### 外部依赖 ## 6. 通信模式
| 依赖 | 用途 | 我们项目是否已有 | Claude in Chrome 支持两种与浏览器通信的方式:
|------|------|----------------|
| `ws` | WebSocket 客户端bridge 模式) | ✅ 有 |
| `@modelcontextprotocol/sdk` | MCP Server + 类型 | ✅ 有 |
| `fs`/`net`/`os`/`path` | Node.js 内置 | ✅ |
## 5. 修复步骤 ### 本地 Socket默认
### 步骤 1复制完整实现到 stub 包目录 Chrome 扩展通过 Native Messaging Host 与 CLI 建立 Unix socket 连接。适用于本地开发,无需额外配置。
```bash ### Bridge WebSocket
# 从参考项目复制 7 个文件(覆盖现有的 1 个 stub
cp "E:/源码/claude-code-source-main/claude-code-source-main/deps/@ant/claude-for-chrome-mcp/src/"*.ts \
"E:/源码/Claude-code-bast/packages/@ant/claude-for-chrome-mcp/src/"
```
复制后 `packages/@ant/claude-for-chrome-mcp/src/` 应包含 8 个文件: 通过 Anthropic 的 bridge 服务中转,支持远程操控浏览器。需要 claude.ai OAuth 登录。
``` ## 7. 常见问题
packages/@ant/claude-for-chrome-mcp/src/
├── index.ts ← 覆盖 stub15 行,导出入口)
├── types.ts ← 新增134 行)
├── browserTools.ts ← 新增546 行)
├── mcpServer.ts ← 新增96 行)
├── mcpSocketClient.ts ← 新增493 行)
├── mcpSocketPool.ts ← 新增327 行)
├── bridgeClient.ts ← 新增1126 行)
└── toolCalls.ts ← 新增301 行)
```
### 步骤 2验证构建 ### 扩展显示未安装
```bash 确认已从 Chrome Web Store 安装 "Claude in Chrome" 扩展,安装后重启浏览器。
bun run build
```
不需要改 `scripts/dev.ts``build.ts`(无 feature flag ### 工具未出现在工具列表
### 步骤 3功能验证 检查启动时是否加了 `--chrome` 参数,或通过 `/chrome` 命令确认状态。
```bash ### 连接超时
# 启动(手动启用 chrome
bun run dev -- --chrome
# 在 REPL 中: 确保 Chrome 浏览器正在运行且扩展已启用。Native Messaging Host 在扩展安装时自动注册,如果重装过扩展需要重启浏览器。
# 1. /chrome 命令应显示 Chrome 设置菜单
# 2. 如果 Chrome 扩展已安装 → 状态显示 "Enabled"
# 3. 如果未安装 → 提示安装扩展链接
```
## 6. 验证测试项 ### 不使用 Chrome 功能时
### 6.1 构建验证 不带 `--chrome` 参数正常启动即可,不会加载任何浏览器相关模块,不影响其他功能。
| 测试项 | 预期结果 | 验证命令 |
|--------|---------|---------|
| build 成功 | 无报错 | `bun run build` |
| BROWSER_TOOLS 非空 | 产物中包含 17 个工具定义 | `grep "javascript_tool" dist/*.js` |
| createClaudeForChromeMcpServer 非 null | 产物中包含 MCP Server 创建逻辑 | `grep "ListToolsRequestSchema" dist/*.js` |
| Bridge WebSocket 逻辑在产物中 | 包含 bridge 连接代码 | `grep "bridge.claudeusercontent.com" dist/*.js` |
### 6.2 命令注册验证
| 测试项 | 预期结果 |
|--------|---------|
| `/chrome` 命令可见 | REPL 中输入 `/chrome` 显示设置菜单 |
| `--chrome` 参数可用 | `bun run dev -- --chrome` 不报错 |
| `--no-chrome` 参数可用 | `bun run dev -- --no-chrome` 不报错 |
### 6.3 MCP Server 验证(需要 Chrome 扩展)
| 测试项 | 预期结果 |
|--------|---------|
| Chrome 扩展检测 | 已安装扩展时 `/chrome` 显示 "Extension: Installed" |
| Socket 连接 | 扩展连接后 MCP tools 可用 |
| BROWSER_TOOLS 注册 | `tabs_context_mcp` 等 17 个工具在 MCP 工具列表中可见 |
### 6.4 工具功能验证(需要 Chrome 扩展 + 连接)
| 测试项 | 预期结果 |
|--------|---------|
| `tabs_context_mcp` | 返回当前标签组信息 |
| `navigate` | 能导航到指定 URL |
| `computer` + `screenshot` | 返回页面截图 |
| `read_page` | 返回 DOM 可访问性树 |
| `javascript_tool` | 执行 JS 并返回结果 |
### 6.5 不影响现有功能
| 测试项 | 预期结果 |
|--------|---------|
| 不带 `--chrome` 启动 | 正常运行,无 chrome 相关报错 |
| `/voice` 命令 | 不受影响 |
| `/schedule` 命令 | 不受影响 |
| `bun test` | 现有测试全部通过 |
## 7. 改动总结
| 操作 | 文件 | 说明 |
|------|------|------|
| 覆盖 stub | `packages/@ant/claude-for-chrome-mcp/src/index.ts` | 6 行 stub → 15 行完整导出 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/types.ts` | 134 行类型定义 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/browserTools.ts` | 546 行17 个工具定义 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/mcpServer.ts` | 96 行 MCP Server |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/mcpSocketClient.ts` | 493 行 Socket 客户端 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/mcpSocketPool.ts` | 327 行连接池 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/bridgeClient.ts` | 1126 行 Bridge 客户端 |
| 新增 | `packages/@ant/claude-for-chrome-mcp/src/toolCalls.ts` | 301 行工具调用路由 |
**不改动**`src/` 下所有文件(已与参考项目一致)、`scripts/dev.ts``build.ts`
## 8. 运行时依赖
| 依赖 | 必需? | 说明 |
|------|--------|------|
| Chrome 浏览器 | 是 | 需安装 Chrome |
| Claude in Chrome 扩展 | 是 | 从 https://claude.ai/chrome 安装 |
| claude.ai OAuth 登录 | Bridge 模式需要 | 本地 Socket 模式不需要 |
| Native Messaging Host | 本地 Socket 需要 | 扩展安装时自动注册 |
## 9. 与 /voice、/schedule 恢复方式对比
| 项 | `/schedule` | `/voice` | Claude in Chrome |
|---|---|---|---|
| 编译开关 | `AGENT_TRIGGERS_REMOTE` | `VOICE_MODE` | **无需** |
| 改 dev.ts/build.ts | ✅ | ✅ | **不需要** |
| 缺失的 vendor 二进制 | 无 | `.node` 文件 | 无 |
| 需要替换的 stub | 无 | `audio-capture-napi` | `@ant/claude-for-chrome-mcp`7 个文件) |
| 改动 src/ 源码 | 无 | 无 | 无 |
| 平台限制 | 无 | 需原生 `.node` | 需 Chrome 浏览器 |

View File

@@ -0,0 +1,277 @@
# Computer Use MCP 工具测试报告
> 测试日期: 2026-04-04
> 测试环境: macOS Darwin 25.4.0, Cursor (IDE tier: click)
> MCP Server: `@ant/computer-use-mcp`
## 工具总览
共 17 个工具(含 batch 复合操作),分为 5 大类:
| 类别 | 工具 | 数量 |
|------|------|------|
| 截图/显示 | `screenshot`, `switch_display`, `zoom` | 3 |
| 鼠标操作 | `left_click`, `right_click`, `double_click`, `triple_click`, `middle_click`, `left_click_drag`, `mouse_move` | 7 |
| 键盘操作 | `key`, `type`, `hold_key` | 3 |
| 状态查询 | `cursor_position`, `request_access` | 2 |
| 复合/辅助 | `computer_batch`, `wait` | 2 |
---
## 测试结果
### 1. 权限管理
#### `request_access` — 请求应用访问权限
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 行为 | 弹出系统对话框请求用户授权,支持批量申请多个应用 |
| 返回 | `{ granted: [...], denied: [...], tierGuidance: "..." }` |
| 权限分级 | `click`(仅点击), `full`(完整控制) |
| 说明 | IDE 类应用Cursor、VSCode、Terminal默认授予 `click` tier限制键盘输入和右键操作系统应用System Settings授予 `full` tier |
#### 已授权应用
| 应用 | Tier | 能力 |
|------|------|------|
| Cursor | click | 可见 + 纯左键点击(无键盘输入、右键、修饰键点击、拖拽) |
| Terminal | click | 同上 |
| System Settings | full | 完整控制(键鼠、拖拽等) |
| Finder | — | 已授权 |
---
### 2. 截图与显示
#### `screenshot` — 截取屏幕截图
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 部分通过 |
| 执行 | 工具成功执行,返回 `ok: true` |
| 图片 | **未返回可视图片内容**output 为空字符串) |
| `save_to_disk` | 设置后仍无输出 |
| 分析 | 可能原因:(1) macOS 屏幕录制权限未授予;(2) 当前前台应用未被过滤导致截图为空;(3) MCP 传输层未正确编码图片数据 |
| 建议 | 检查 **系统设置 → 隐私与安全性 → 屏幕录制** 是否授权给运行 Claude Code 的应用 |
#### `switch_display` — 切换显示器
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 行为 | 接受显示器名称或 `"auto"`(自动选择) |
| 返回 | 确认消息 |
#### `zoom` — 区域放大截图
| 项目 | 结果 |
|------|------|
| 状态 | ⏭️ 跳过 |
| 原因 | 依赖 `screenshot` 返回的图片坐标,截图未返回图片无法测试 |
---
### 3. 鼠标操作
> 以下测试在 Cursor 窗口上执行tier: click
#### `mouse_move` — 移动鼠标
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `coordinate: [500, 500]` |
| 返回 | `"Moved."` |
#### `left_click` — 左键单击
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `coordinate: [500, 500]` |
| 返回 | `"Clicked."` |
#### `double_click` — 双击
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `coordinate: [500, 500]` |
| 返回 | `"Clicked."` |
#### `triple_click` — 三击
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `coordinate: [500, 500]` |
| 返回 | `"Clicked."` |
#### `right_click` — 右键点击
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — `"Code" is granted at tier "click" — right-click, middle-click, and clicks with modifier keys require tier "full"` |
| Finder (full tier) | ✅ 通过 — 返回 `"Clicked."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
#### `middle_click` — 中键点击
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — 同 `right_click`,需要 full tier |
| Finder (full tier) | ✅ 通过 — 返回 `"Clicked."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
#### `left_click_drag` — 拖拽
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — 拖拽被视为修饰键点击,需要 full tier |
| Finder (full tier) | ✅ 通过 — 返回 `"Dragged."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
#### `scroll` — 滚轮滚动
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `coordinate: [500, 500]`, `scroll_direction: "down"`, `scroll_amount: 3` |
| 返回 | `"Scrolled."` |
| 反向 | ✅ `scroll_direction: "up"` 也通过 |
---
### 4. 键盘操作
> 以下测试在 Cursor 窗口上执行tier: click— 所有键盘操作均被拒绝
#### `key` — 按键/快捷键
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — IDE tier 限制键盘输入 |
| Finder (full tier) | ✅ 通过 — `escape` 按键成功,返回 `"Key pressed."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
#### `type` — 输入文本
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — IDE tier 限制文本输入 |
| Finder (full tier) | ✅ 通过 — 输入 `"hello"` 成功,返回 `"Typed 5 grapheme(s)."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
#### `hold_key` — 按住按键
| 项目 | 结果 |
|------|------|
| 状态 | ⚠️ 受 tier 限制 |
| Cursor (click tier) | ❌ 被拒绝 — IDE tier 限制键盘输入 |
| Finder (full tier) | ✅ 通过 — 按住 `shift` 1 秒成功,返回 `"Key held."` |
| 结论 | 功能正常IDE 安全限制符合预期 |
---
### 5. 状态查询
#### `cursor_position` — 获取鼠标位置
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 返回 | `{"x": null, "y": null, "coordinateSpace": "image_pixels"}` |
| 说明 | 坐标为 null 是因为没有成功截图,无参考坐标系 |
---
### 6. 复合/辅助操作
#### `computer_batch` — 批量执行操作
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 行为 | 按顺序执行操作列表,遇到失败则停止后续操作 |
| 返回 | `{ completed: [...], failed: {...}, remaining: N }` |
| 特点 | 单次 API 调用执行多个操作,减少往返延迟 |
| 错误处理 | 失败的操作会中断后续操作,返回已完成和剩余数量 |
#### `wait` — 等待
| 项目 | 结果 |
|------|------|
| 状态 | ✅ 通过 |
| 输入 | `duration: 1` (秒) |
| 返回 | `"Waited 1s."` |
| 最大值 | 100 秒 |
---
## 汇总统计
| 状态 | 数量 | 工具 |
|------|------|------|
| ✅ 通过 | 10 | `request_access`, `switch_display`, `mouse_move`, `left_click`, `double_click`, `triple_click`, `scroll`, `cursor_position`, `computer_batch`, `wait` |
| ⚠️ 部分通过 | 7 | `screenshot`(执行成功但无图片返回), `right_click`, `middle_click`, `left_click_drag`, `key`, `type`, `hold_key`(均在 full tier 应用上通过IDE click tier 限制是预期行为) |
| ❌ 被拒绝 | 0 | — |
| ⏭️ 跳过 | 1 | `zoom`(依赖截图) |
---
## 已知问题
### P0: 截图无图片返回
`screenshot` 工具执行成功但未返回图片内容,导致:
- 无法获取屏幕坐标参考
- `cursor_position` 返回 null 坐标
- `zoom` 无法使用
- 所有点击操作只能盲点(无截图验证)
**可能原因**:
1. macOS 屏幕录制权限未授予
2. MCP 图片传输/编码问题
3. 截图内容被安全过滤机制过滤
**建议排查**: 检查 `系统设置 → 隐私与安全性 → 屏幕录制` 权限。
### P1: IDE 应用键盘操作受限 — ✅ 已确认功能正常
IDE 类应用Cursor、VSCode、Terminal被限制在 `click` tier无法执行
- 键盘输入(`key`, `type`, `hold_key`
- 右键/中键点击(`right_click`, `middle_click`
- 拖拽操作(`left_click_drag`
这是安全设计,防止 AI 操控 IDE 终端。**在 full tier 应用Finder、System Settings以上 6 个操作均测试通过,功能完全正常。**
---
## 权限模型说明
Computer Use MCP 采用分级权限模型:
```
┌─────────────────────────────────────────┐
│ Tier: full │
│ - 所有鼠标操作(左键、右键、中键、拖拽) │
│ - 键盘输入type, key, hold_key
│ - 适用于: 系统应用、Finder 等 │
├─────────────────────────────────────────┤
│ Tier: click │
│ - 仅纯左键点击 │
│ - 滚轮滚动 │
│ - 适用于: IDE、Terminal 等 │
├─────────────────────────────────────────┤
│ 未授权 │
│ - 所有操作被拒绝 │
│ - 需通过 request_access 申请 │
└─────────────────────────────────────────┘
```

View File

@@ -1,197 +1,136 @@
# Computer Use — macOS / Windows / Linux 跨平台实施计划 # Computer Use 用户指南
更新时间2026-04-03 Computer Use 让 Claude 直接操控你的电脑——移动鼠标、点击、输入文字、截图,就像一个远程助手坐在你面前操作一样。
参考项目:`E:\源码\claude-code-source-main\claude-code-source-main`
## 1. 现状 ## 支持平台
参考项目的 Computer Use **仅支持 macOS**——从入口到底层全部写死 darwin。我们的项目在 Phase 1-3 中已经完成了: | 平台 | 状态 | 额外配置 |
|------|------|---------|
| macOS | 可用 | 需授予辅助功能 + 屏幕录制权限 |
| Windows | 可用 | 无需额外配置 |
| Linux | 不可用 | 后端待开发 |
-`@ant/computer-use-mcp` stub 替换为完整实现12 文件) ## 快速开始
-`@ant/computer-use-input` 拆为 dispatcher + backendsdarwin + win32
-`@ant/computer-use-swift` 拆为 dispatcher + backendsdarwin + win32
-`CHICAGO_MCP` 编译开关已开
-`src/` 层有 6 处 macOS 硬编码阻塞
## 2. 阻塞点全景 1. 启动 Claude Code
### 2.1 入口层 ```bash
bun run dev
```
| # | 文件:行号 | 阻塞代码 | 影响 | Computer Use 默认已开启,无需额外参数。
|---|----------|---------|------|
| 1 | `src/main.tsx:1605` | `getPlatform() === 'macos'` | 整个 CU 初始化被跳过 |
### 2.2 加载层 2. 在对话中告诉 Claude 你想做什么,例如:
- "帮我打开系统设置"
- "截个屏看看当前桌面"
- "在 Finder 里点击那个文件"
| # | 文件:行号 | 阻塞代码 | 影响 | 3. 首次操控某个应用时,会弹出权限对话框让你确认。
|---|----------|---------|------|
| 2 | `src/utils/computerUse/swiftLoader.ts:16` | `process.platform !== 'darwin'` → throw | 截图、应用管理全部不可用 |
| 3 | `src/utils/computerUse/executor.ts:263` | `process.platform !== 'darwin'` → throw | 整个 executor 工厂函数不可用 |
### 2.3 macOS 特有依赖 4. 操作过程中随时按 **Esc**macOS或 **Ctrl+C**Windows中止。
| # | 文件:行号 | 依赖 | macOS 实现 | 需要替代方案 | ## 权限说明
|---|----------|------|-----------|------------|
| 4 | `executor.ts:70-88` | 剪贴板 | `pbcopy`/`pbpaste` | Win: PowerShell `Get/Set-Clipboard`Linux: `xclip`/`wl-copy` |
| 5 | `drainRunLoop.ts:21` | CFRunLoop pump | `cu._drainMainRunLoop()` | 非 darwin直接执行 fn(),不需要 pump |
| 6 | `escHotkey.ts:28` | ESC 热键 | CGEventTap | 非 darwin返回 false已有 Ctrl+C fallback |
| 7 | `hostAdapter.ts:48-54` | 系统权限 | TCC accessibility + screenRecording | Win直接 grantedLinux检查 xdotool |
| 8 | `common.ts:56` | 平台标识 | `platform: 'darwin'` 硬编码 | 动态获取 |
| 9 | `executor.ts:180` | 粘贴快捷键 | `command+v` | Win/Linux`ctrl+v` |
### 2.4 缺失的 Linux 后端 Computer Use 采用分级权限模型,保护你的安全:
| | macOS | Windows | Linux | | 级别 | 能力 | 适用场景 |
|---|-------|---------|-------| |------|------|---------|
| `computer-use-input/backends/` | ✅ darwin.ts | ✅ win32.ts | ❌ 需新建 linux.ts | | **full** | 所有操作:鼠标点击(左/右/中键)、拖拽、键盘输入、组合键 | 系统设置、Finder 等系统应用 |
| `computer-use-swift/backends/` | ✅ darwin.ts | ✅ win32.ts | ❌ 需新建 linux.ts | | **click** | 仅左键点击和滚轮滚动 | IDEVS Code、Cursor、终端 |
| 未授权 | 所有操作被拒绝 | 需要通过 `request_access` 申请 |
## 3. 每个平台的能力依赖 IDE 类应用默认只有 click 权限,这是安全设计——防止 AI 在你的终端或编辑器中执行危险操作。如需完整控制,可以在权限对话框中手动提升。
### 3.1 computer-use-input键鼠 ## 可用操作
| 功能 | macOS | Windows | Linux | ### 鼠标
|------|-------|---------|-------|
| 鼠标移动 | CGEvent JXA | SetCursorPos P/Invoke | xdotool mousemove |
| 鼠标点击 | CGEvent JXA | SendInput P/Invoke | xdotool click |
| 鼠标滚轮 | CGEvent JXA | SendInput MOUSEEVENTF_WHEEL | xdotool scroll |
| 键盘按键 | System Events osascript | keybd_event P/Invoke | xdotool key |
| 组合键 | System Events osascript | keybd_event 组合 | xdotool key combo |
| 文本输入 | System Events keystroke | SendKeys.SendWait | xdotool type |
| 前台应用 | System Events osascript | GetForegroundWindow P/Invoke | xdotool getactivewindow + /proc |
| 工具依赖 | osascript内置 | powershell内置 | xdotool需安装 |
### 3.2 computer-use-swift截图 + 应用管理) | 操作 | 说明 |
|------|------|
| 移动鼠标 | 移动到指定坐标 |
| 左键点击 | 单击、双击、三击 |
| 右键点击 | 需要 full 权限 |
| 中键点击 | 需要 full 权限 |
| 拖拽 | 从 A 点拖到 B 点,需要 full 权限 |
| 滚轮 | 向上或向下滚动 |
| 功能 | macOS | Windows | Linux | ### 键盘
|------|-------|---------|-------|
| 全屏截图 | screencapture | CopyFromScreen | gnome-screenshot / scrot / grim |
| 区域截图 | screencapture -R | CopyFromScreen(rect) | gnome-screenshot -a / scrot -a / grim -g |
| 显示器列表 | CGGetActiveDisplayList JXA | Screen.AllScreens | xrandr --query |
| 运行中应用 | System Events JXA | Get-Process | wmctrl -l / ps |
| 打开应用 | osascript activate | Start-Process | xdg-open / gtk-launch |
| 隐藏/显示 | System Events visibility | ShowWindow/SetForegroundWindow | wmctrl -c / xdotool |
| 工具依赖 | screencapture + osascript | powershell | xdotool + scrot/grim + wmctrl |
### 3.3 executor 层 | 操作 | 说明 |
|------|------|
| 按键 | 单个按键或组合键(如 Ctrl+C |
| 输入文字 | 逐字符输入文本,需要 full 权限 |
| 长按 | 按住某个键一段时间,需要 full 权限 |
| 功能 | macOS | Windows | Linux | ### 屏幕
|------|-------|---------|-------|
| drainRunLoop | CFRunLoop pump | 不需要 | 不需要 |
| ESC 热键 | CGEventTap | 跳过Ctrl+C fallback | 跳过Ctrl+C fallback |
| 剪贴板读 | pbpaste | `powershell Get-Clipboard` | xclip -o / wl-paste |
| 剪贴板写 | pbcopy | `powershell Set-Clipboard` | xclip / wl-copy |
| 粘贴快捷键 | command+v | ctrl+v | ctrl+v |
| 终端检测 | __CFBundleIdentifier | WT_SESSION / TERM_PROGRAM | TERM_PROGRAM |
| 系统权限 | TCC check | 直接 granted | 检查 xdotool 安装 |
## 4. 执行步骤 | 操作 | 说明 |
|------|------|
| 截图 | 截取当前屏幕 |
| 切换显示器 | 多显示器环境下切换目标屏幕 |
| 缩放 | 放大屏幕某个区域 |
### Phase 1已完成 ✅ ### 其他
- [x] `@ant/computer-use-mcp` stub → 完整实现 | 操作 | 说明 |
- [x] `@ant/computer-use-input` dispatcher + darwin/win32 backends |------|------|
- [x] `@ant/computer-use-swift` dispatcher + darwin/win32 backends | 获取鼠标位置 | 查询当前鼠标坐标 |
- [x] `CHICAGO_MCP` 编译开关 | 批量操作 | 一次执行多个操作,减少等待 |
| 等待 | 暂停指定秒数(最长 100 秒) |
### Phase 2移除 6 处 macOS 硬编码(解锁 macOS + Windows ## macOS 权限配置
**改动原则macOS 代码路径不变,只在每处 darwin 守卫后加 win32/linux 分支。** 首次使用前,需要授予两项系统权限。缺少任一项都会导致功能异常(见下方说明)。
| 步骤 | 文件 | 改动 | ### 辅助功能Accessibility
|------|------|------|
| 2.1 | `src/main.tsx:1605` | `getPlatform() === 'macos'` → 去掉平台限制,或改为 `!== 'unknown'` |
| 2.2 | `src/utils/computerUse/swiftLoader.ts:16-18` | 移除 `process.platform !== 'darwin'` throw。`@ant/computer-use-swift/index.ts` 已有跨平台 dispatch |
| 2.3 | `src/utils/computerUse/executor.ts:263-267` | 移除 `process.platform !== 'darwin'` throw。改为检查 input/swift isSupported |
| 2.4 | `src/utils/computerUse/executor.ts:70-88` | 剪贴板函数按平台分发darwin→pbcopy/pbpastewin32→PowerShell Get/Set-Clipboardlinux→xclip |
| 2.5 | `src/utils/computerUse/executor.ts:180` | `typeViaClipboard``command+v` → 非 darwin 时用 `ctrl+v` |
| 2.6 | `src/utils/computerUse/executor.ts:273` | `const cu = requireComputerUseSwift()` → 改为 `new ComputerUseAPI()`(从 package 直接实例化,不走 swiftLoader throw |
| 2.7 | `src/utils/computerUse/drainRunLoop.ts` | 开头加 `if (process.platform !== 'darwin') return fn()` |
| 2.8 | `src/utils/computerUse/escHotkey.ts` | `registerEscHotkey` 非 darwin 返回 false已有 Ctrl+C fallback |
| 2.9 | `src/utils/computerUse/hostAdapter.ts:48-54` | `ensureOsPermissions` 非 darwin 返回 `{ granted: true }` |
| 2.10 | `src/utils/computerUse/common.ts:56` | `platform: 'darwin'``platform: process.platform === 'win32' ? 'windows' : process.platform === 'linux' ? 'linux' : 'darwin'` |
| 2.11 | `src/utils/computerUse/common.ts:55` | `screenshotFiltering: 'native'` → 非 darwin 时 `'none'`Windows/Linux 截图不支持 per-app 过滤) |
| 2.12 | `src/utils/computerUse/gates.ts:13` | `enabled: false``enabled: true`(无 GrowthBook 时默认可用) |
| 2.13 | `src/utils/computerUse/gates.ts:39-43` | `hasRequiredSubscription()` → 直接返回 `true` |
### Phase 3新增 Linux 后端 允许 Claude 控制鼠标和键盘。
| 步骤 | 文件 | 内容 | 1. 打开 **系统设置 → 隐私与安全性 → 辅助功能**
|------|------|------| 2. 点击左下角锁图标解锁(需要管理员密码)
| 3.1 | `packages/@ant/computer-use-input/src/backends/linux.ts` | xdotool 键鼠mousemove/click/key/type/getactivewindow | 3. 将运行 Claude Code 的应用添加到允许列表:
| 3.2 | `packages/@ant/computer-use-swift/src/backends/linux.ts` | scrot/grim 截图 + xrandr 显示器 + wmctrl 窗口管理 | - Terminal → `Terminal.app`
| 3.3 | `packages/@ant/computer-use-input/src/index.ts` | dispatcher 加 `case 'linux'` | - iTerm → `iTerm.app`
| 3.4 | `packages/@ant/computer-use-swift/src/index.ts` | dispatcher 加 `case 'linux'` | - Cursor → `Cursor.app`
- VS Code 终端 → `Electron` 或 `Visual Studio Code.app`
4. 确保应用旁边的开关已打开
### Phase 4验证 **未授予时的现象**:鼠标移动、点击、键盘输入均无反应,工具执行成功但屏幕没有任何变化。
| 测试项 | macOS | Windows | Linux | ### 屏幕录制Screen Recording
|--------|-------|---------|-------|
| build 成功 | ✅ | 验证 | 验证 |
| MCP 工具列表非空 | 验证 | 验证 | 验证 |
| 鼠标移动 | 验证 | ✅ 已通过 | 验证 |
| 截图 | 验证 | ✅ 已通过 | 验证 |
| 键盘输入 | 验证 | 验证 | 验证 |
| 前台窗口 | 验证 | ✅ 已通过 | 验证 |
| 剪贴板 | 验证 | 验证 | 验证 |
## 5. 文件改动总览 允许 Claude 截取屏幕内容。
### 不动的文件14 个) 1. 打开 **系统设置 → 隐私与安全性 → 屏幕录制**
2. 将同一个应用添加到允许列表并开启开关
3. **需要重启该应用**才能生效(系统会提示 "xxx 需要重新打开"
`cleanup.ts``computerUseLock.ts``wrapper.tsx``toolRendering.tsx``mcpServer.ts``setup.ts``appNames.ts``inputLoader.ts``src/services/mcp/client.ts``@ant/computer-use-mcp/src/*`Phase 1 已完成)、`backends/darwin.ts`(两个包都不动) **未授予时的现象**截图工具执行成功但返回空白图片Claude 无法看到你的屏幕,所有点击操作变成"盲点"。
### 改 src/ 的文件8 个) ### 验证权限
| 文件 | 改动量 | 风险 | 授予两项权限后,重启 Claude Code在对话中让 Claude 截一张图即可验证是否配置成功。如果截图内容正常显示,说明权限配置完成。
|------|--------|------|
| `main.tsx` | 1 行 | 低 |
| `swiftLoader.ts` | 2 行 | 低 |
| `executor.ts` | ~40 行(剪贴板分发 + 平台守卫 + paste 快捷键) | **中** |
| `drainRunLoop.ts` | 1 行 | 低 |
| `escHotkey.ts` | 3 行 | 低 |
| `hostAdapter.ts` | 5 行 | 低 |
| `common.ts` | 3 行 | 低 |
| `gates.ts` | 3 行 | 低 |
### 新增文件2 个 ## Linux 依赖(暂不可用
| 文件 | 行数估算 | Linux 后端尚未开发。完成后需要安装以下工具:
|------|---------|
| `packages/@ant/computer-use-input/src/backends/linux.ts` | ~150 行 |
| `packages/@ant/computer-use-swift/src/backends/linux.ts` | ~200 行 |
## 6. Linux 依赖工具 ```bash
sudo apt install xdotool scrot xclip wmctrl
| 工具 | 用途 | 安装命令Ubuntu |
|------|------|-------------------|
| `xdotool` | 键鼠模拟 + 窗口管理 | `sudo apt install xdotool` |
| `scrot``gnome-screenshot` | 截图 | `sudo apt install scrot` |
| `xrandr` | 显示器信息 | 通常已预装 |
| `xclip` | 剪贴板 | `sudo apt install xclip` |
| `wmctrl` | 窗口列表/切换 | `sudo apt install wmctrl` |
Wayland 环境需要替代工具:`ydotool`(替代 xdotool`grim`(替代 scrot`wl-clipboard`(替代 xclip。初期可先只支持 X11Wayland 标记为 todo。
## 7. 执行顺序建议
```
Phase 2解锁 macOS + Windows
├── 2.1-2.3 移除 3 处硬编码 throw/skip
├── 2.4-2.5 剪贴板 + 粘贴快捷键平台分发
├── 2.6 swiftLoader → 直接实例化
├── 2.7-2.9 drainRunLoop / escHotkey / permissions 平台分支
├── 2.10-2.11 common.ts 平台标识动态化
├── 2.12-2.13 gates.ts 默认值
└── 验证 Windows
Phase 3Linux 后端)
├── 3.1 input/backends/linux.ts
├── 3.2 swift/backends/linux.ts
├── 3.3-3.4 dispatcher 加 linux case
└── 验证 Linux
Phase 4集成验证 + PR
``` ```
每个 Phase 可独立验证、独立提交。Phase 2 完成后 macOS + Windows 可用Phase 3 完成后三平台全部可用。 仅支持 X11Wayland 不支持。
## 常见问题
### 截图成功但看不到图片
检查 **系统设置 → 隐私与安全性 → 屏幕录制** 是否已授权。未授权时截图工具会执行成功但返回空白内容。
### IDE 中无法输入文字或右键
这是正常行为。IDE 类应用只有 click 权限,无法执行键盘输入、右键、拖拽等操作。如需完整控制,请在系统应用(如 Finder中操作。
### 操作中途想停止
**Esc**macOS**Ctrl+C** 即可立即中止。

View File

@@ -796,6 +796,17 @@ function resolveRequestedApps(
if (!resolved) { if (!resolved) {
resolved = byLowerDisplayName.get(requested.toLowerCase()); resolved = byLowerDisplayName.get(requested.toLowerCase());
} }
// Fuzzy fallback: match requested name as substring of display name
// e.g. "Chrome" matches "Google Chrome", "Code" matches "Visual Studio Code"
if (!resolved) {
const lower = requested.toLowerCase();
for (const app of installed) {
if (app.displayName.toLowerCase().includes(lower)) {
resolved = app;
break;
}
}
}
const bundleId = resolved?.bundleId; const bundleId = resolved?.bundleId;
// When unresolved AND the requested string looks like a bundle ID, use it // When unresolved AND the requested string looks like a bundle ID, use it
// directly for tier lookup (e.g. "company.thebrowser.Browser" with Arc not // directly for tier lookup (e.g. "company.thebrowser.Browser" with Arc not

View File

@@ -159,23 +159,28 @@ export const apps: AppsAPI = {
async listInstalled() { async listInstalled() {
try { try {
const result = await osascript(` // Use Spotlight (mdfind) to enumerate .app bundles and mdls to get real bundle IDs.
tell application "System Events" // Searches /Applications, /System/Applications, and /System/Applications/Utilities
set appList to "" // so that system apps (Terminal, Chess, etc.) and core services (Finder) are found.
repeat with appFile in (every file of folder "Applications" of startup disk whose name ends with ".app") const proc = Bun.spawn([
set appPath to POSIX path of (appFile as alias) 'bash', '-c',
set appName to name of appFile `for dir in /Applications /System/Applications /System/Applications/Utilities /System/Library/CoreServices; do
set appList to appList & appPath & "|" & appName & "\\n" mdfind 'kMDItemContentType == "com.apple.application-bundle"' -onlyin "$dir" 2>/dev/null
end repeat done | sort -u | while read -r appPath; do
return appList bundleId=$(mdls -raw -name kMDItemCFBundleIdentifier "$appPath" 2>/dev/null)
end tell if [ -n "$bundleId" ] && [ "$bundleId" != "(null)" ]; then
`) displayName=$(basename "$appPath" .app)
return result.split('\n').filter(Boolean).map(line => { echo "$bundleId|$displayName|$appPath"
const [path, name] = line.split('|', 2) fi
const displayName = (name ?? '').replace(/\.app$/, '') done`,
], { stdout: 'pipe', stderr: 'pipe' })
const text = await new Response(proc.stdout).text()
await proc.exited
return text.split('\n').filter(Boolean).map(line => {
const [bundleId, displayName, path] = line.split('|', 3)
return { return {
bundleId: `com.app.${displayName.toLowerCase().replace(/\s+/g, '-')}`, bundleId: bundleId ?? '',
displayName, displayName: displayName ?? '',
path: path ?? '', path: path ?? '',
} }
}) })

View File

@@ -80,6 +80,12 @@ export class ComputerUseAPI {
async captureRegion() { throw new Error('computer-use-swift: no backend for this platform') }, async captureRegion() { throw new Error('computer-use-swift: no backend for this platform') },
} }
hotkey = (backend as any)?.hotkey ?? {
registerEscape(_cb: () => void): boolean { return false },
unregister() {},
notifyExpectedEscape() {},
}
async resolvePrepareCapture( async resolvePrepareCapture(
allowedBundleIds: string[], allowedBundleIds: string[],
_surrogateHost: string, _surrogateHost: string,

View File

@@ -46,9 +46,16 @@ export function getComputerUseHostAdapter(): ComputerUseHostAdapter {
}), }),
ensureOsPermissions: async () => { ensureOsPermissions: async () => {
if (process.platform !== 'darwin') return { granted: true } if (process.platform !== 'darwin') return { granted: true }
const cu = requireComputerUseSwift() const cu = requireComputerUseSwift() as any
const accessibility = (cu as any).tcc.checkAccessibility() // Native .node module exposes tcc; cross-platform JS backend does not.
const screenRecording = (cu as any).tcc.checkScreenRecording() // When tcc is absent (JS backend on macOS), we cannot programmatically
// check TCC status — returning granted:false would create a deadlock
// (recheck also fails, user can never pass). The JS backend uses
// osascript/screencapture which trigger OS-level permission prompts
// themselves, so the OS provides the safety net instead.
if (!cu.tcc) return { granted: true }
const accessibility = cu.tcc.checkAccessibility()
const screenRecording = cu.tcc.checkScreenRecording()
return accessibility && screenRecording return accessibility && screenRecording
? { granted: true } ? { granted: true }
: { granted: false, accessibility, screenRecording } : { granted: false, accessibility, screenRecording }