mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
Merge remote-tracking branch 'amDosion/feat/computer-use-windows'
This commit is contained in:
315
docs/features/computer-use-windows-enhancement.md
Normal file
315
docs/features/computer-use-windows-enhancement.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# Computer Use Windows 增强实施计划
|
||||
|
||||
更新时间:2026-04-03
|
||||
依赖文档:`docs/features/windows-ai-desktop-control.md`、`docs/features/computer-use.md`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
在已有的 PowerShell 子进程方案基础上,利用 Windows 原生 API 增强 Computer Use 的 Windows 实现,解决 3 个核心问题:
|
||||
|
||||
1. **窗口绑定截图**:当前 `CopyFromScreen` 只能全屏截图,无法对指定窗口截图(尤其是被遮挡/最小化窗口)
|
||||
2. **UI 结构感知**:当前只能通过坐标点击,无法像 macOS Accessibility 那样理解 UI 元素树
|
||||
3. **性能**:每次 PowerShell 启动约 273ms,剪贴板/窗口枚举等高频操作需要更快的方式
|
||||
|
||||
## 2. 已验证的 Windows API 能力
|
||||
|
||||
以下 API 全部通过 PowerShell P/Invoke 实测通过:
|
||||
|
||||
| 能力 | API | 验证结果 |
|
||||
|------|-----|---------|
|
||||
| 窗口绑定截图 | `PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT)` | ✅ VS Code 342KB, Chrome 273KB |
|
||||
| 枚举窗口+HWND | `EnumWindows` + `GetWindowText` + `GetWindowThreadProcessId` | ✅ 38 个窗口,含 HWND/PID/标题 |
|
||||
| UI 元素树 | `System.Windows.Automation.AutomationElement` | ✅ 记事本 39 个元素 |
|
||||
| UI 写值 | `ValuePattern.SetValue()` | ✅ 成功写入记事本文本 |
|
||||
| UI 点击 | `InvokePattern.Invoke()` | ✅ 按钮可程序化点击 |
|
||||
| 坐标元素识别 | `AutomationElement.FromPoint(x, y)` | ✅ 返回元素类型+名称 |
|
||||
| OCR | `Windows.Media.Ocr.OcrEngine` | ✅ 英语+中文引擎可用 |
|
||||
| 全局热键 | `RegisterHotKey` | ✅ API 可调 |
|
||||
| 剪贴板直接操作 | `System.Windows.Forms.Clipboard` | ✅ 读/写/图片检测 |
|
||||
| Shell 启动 | `ShellExecute` | ✅ 打开文件/URL/应用 |
|
||||
|
||||
## 3. 架构设计
|
||||
|
||||
### 3.1 文件结构
|
||||
|
||||
在现有 `backends/win32.ts` 基础上新增 Windows 专属模块:
|
||||
|
||||
```
|
||||
packages/@ant/computer-use-input/src/
|
||||
├── backends/
|
||||
│ ├── darwin.ts ← 不动
|
||||
│ ├── win32.ts ← 增强:直接 Win32 API 替代部分 PowerShell
|
||||
│ └── linux.ts ← 不动
|
||||
|
||||
packages/@ant/computer-use-swift/src/
|
||||
├── backends/
|
||||
│ ├── darwin.ts ← 不动
|
||||
│ ├── win32.ts ← 增强:PrintWindow 窗口截图 + EnumWindows
|
||||
│ └── linux.ts ← 不动
|
||||
|
||||
packages/@ant/computer-use-mcp/src/
|
||||
│ └── tools.ts ← 增加 Windows 专属工具定义(UI Automation、OCR)
|
||||
|
||||
src/utils/computerUse/
|
||||
│ └── win32/ ← 新增目录:Windows 专属能力
|
||||
│ ├── uiAutomation.ts ← UI 元素树、点击、写值
|
||||
│ ├── ocr.ts ← 截图 + OCR 文字识别
|
||||
│ ├── windowCapture.ts ← PrintWindow 窗口绑定截图
|
||||
│ └── windowEnum.ts ← EnumWindows 窗口枚举
|
||||
```
|
||||
|
||||
### 3.2 分层
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ Computer Use MCP Tools │
|
||||
│ screenshot / click / type / request_access │
|
||||
│ + Windows 专属: ui_tree / ocr / window_cap │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ src/utils/computerUse/ │
|
||||
│ executor.ts → 按平台 dispatch │
|
||||
│ win32/ → Windows 专属能力模块 │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ packages/@ant/computer-use-{input,swift} │
|
||||
│ backends/win32.ts → PowerShell + Win32 API │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Windows Native API │
|
||||
│ PrintWindow / EnumWindows / UI Automation │
|
||||
│ SendInput / Clipboard / OCR / ShellExecute │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 4. 实施计划
|
||||
|
||||
### Phase A:窗口绑定截图(解决核心问题)
|
||||
|
||||
**问题**:当前 `CopyFromScreen` 只能全屏截图,无法对指定窗口截图。
|
||||
**方案**:用 `PrintWindow` + `FindWindow` 实现窗口级截图。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| A.1 | `src/utils/computerUse/win32/windowCapture.ts` | 新建:`captureWindow(title)` 用 PrintWindow 截取指定窗口 |
|
||||
| A.2 | `src/utils/computerUse/win32/windowEnum.ts` | 新建:`listWindows()` 用 EnumWindows 返回 {hwnd, pid, title}[] |
|
||||
| A.3 | `packages/@ant/computer-use-swift/src/backends/win32.ts` | `screenshot.captureExcluding` 增加按窗口截图能力 |
|
||||
| A.4 | `packages/@ant/computer-use-swift/src/backends/win32.ts` | `apps.listRunning` 用 EnumWindows 替代 Get-Process(返回 HWND) |
|
||||
|
||||
**PowerShell 脚本核心**:
|
||||
|
||||
```powershell
|
||||
# PrintWindow 截取指定窗口
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
Add-Type -ReferencedAssemblies System.Drawing @'
|
||||
using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging;
|
||||
public class WinCap {
|
||||
[DllImport("user32.dll", CharSet=CharSet.Unicode)]
|
||||
public static extern IntPtr FindWindow(string c, string t);
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr h, out RECT r);
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool PrintWindow(IntPtr h, IntPtr hdc, uint f);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT { public int L, T, R, B; }
|
||||
// ... CaptureByTitle(string title) → base64
|
||||
}
|
||||
'@
|
||||
```
|
||||
|
||||
**验证标准**:
|
||||
- 能按窗口标题截图
|
||||
- 被遮挡的窗口也能截图
|
||||
- 返回 base64 + width + height
|
||||
|
||||
### Phase B:UI Automation(Windows 专属新能力)
|
||||
|
||||
**问题**:macOS 有 Accessibility API 可以读取/操作 UI 元素,Windows 当前只能坐标点击。
|
||||
**方案**:用 `System.Windows.Automation` 实现 UI 树读取和元素操作。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| B.1 | `src/utils/computerUse/win32/uiAutomation.ts` | 新建:核心 UIA 操作封装 |
|
||||
| B.2 | `packages/@ant/computer-use-mcp/src/tools.ts` | 增加 Windows 专属工具定义 |
|
||||
|
||||
**uiAutomation.ts 导出函数**:
|
||||
|
||||
```typescript
|
||||
// 获取窗口的 UI 元素树
|
||||
getUITree(windowTitle: string, depth: number): UIElement[]
|
||||
|
||||
// 按名称/类型/AutomationId 查找元素
|
||||
findElement(windowTitle: string, query: {name?, controlType?, automationId?}): UIElement | null
|
||||
|
||||
// 点击元素(InvokePattern)
|
||||
clickElement(windowTitle: string, automationId: string): boolean
|
||||
|
||||
// 设置元素值(ValuePattern)
|
||||
setValue(windowTitle: string, automationId: string, value: string): boolean
|
||||
|
||||
// 获取坐标处的元素
|
||||
elementAtPoint(x: number, y: number): UIElement | null
|
||||
```
|
||||
|
||||
**UIElement 类型**:
|
||||
```typescript
|
||||
interface UIElement {
|
||||
name: string
|
||||
controlType: string // Button, Edit, Text, List, etc.
|
||||
automationId: string
|
||||
boundingRect: { x: number, y: number, w: number, h: number }
|
||||
isEnabled: boolean
|
||||
value?: string // ValuePattern 可用时
|
||||
children?: UIElement[]
|
||||
}
|
||||
```
|
||||
|
||||
**PowerShell 脚本核心**:
|
||||
```powershell
|
||||
Add-Type -AssemblyName UIAutomationClient
|
||||
Add-Type -AssemblyName UIAutomationTypes
|
||||
|
||||
# 读取 UI 树
|
||||
$root = [AutomationElement]::RootElement
|
||||
$window = $root.FindFirst([TreeScope]::Children,
|
||||
[PropertyCondition]::new([AutomationElement]::NameProperty, $title))
|
||||
$elements = $window.FindAll([TreeScope]::Descendants, [Condition]::TrueCondition)
|
||||
|
||||
# 写入文本
|
||||
$element.GetCurrentPattern([ValuePattern]::Pattern).SetValue($text)
|
||||
|
||||
# 点击按钮
|
||||
$element.GetCurrentPattern([InvokePattern]::Pattern).Invoke()
|
||||
```
|
||||
|
||||
**验证标准**:
|
||||
- 能读取记事本的 UI 树(按钮、文本框、菜单)
|
||||
- 能向文本框写入内容
|
||||
- 能点击按钮
|
||||
- 能识别坐标处的元素
|
||||
|
||||
### Phase C:OCR 屏幕文字识别
|
||||
|
||||
**问题**:截图后 AI 只能看到图片,无法直接读取文字。
|
||||
**方案**:用 `Windows.Media.Ocr` 对截图进行文字识别。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| C.1 | `src/utils/computerUse/win32/ocr.ts` | 新建:截图 + OCR 识别 |
|
||||
| C.2 | `packages/@ant/computer-use-mcp/src/tools.ts` | 增加 `screen_ocr` 工具定义 |
|
||||
|
||||
**ocr.ts 导出函数**:
|
||||
```typescript
|
||||
// 对屏幕区域 OCR
|
||||
ocrRegion(x: number, y: number, w: number, h: number, lang?: string): OcrResult
|
||||
|
||||
// 对指定窗口 OCR
|
||||
ocrWindow(windowTitle: string, lang?: string): OcrResult
|
||||
|
||||
interface OcrResult {
|
||||
text: string
|
||||
lines: { text: string, bounds: {x,y,w,h} }[]
|
||||
language: string
|
||||
}
|
||||
```
|
||||
|
||||
**已确认可用语言**:英语 (en-US) + 中文 (zh-Hans-CN)
|
||||
|
||||
**验证标准**:
|
||||
- 能识别屏幕区域中的英文和中文
|
||||
- 返回文字内容 + 每行的位置信息
|
||||
|
||||
### Phase D:高频操作性能优化
|
||||
|
||||
**问题**:每次 PowerShell 启动 273ms,鼠标移动等高频操作太慢。
|
||||
**方案**:用 .NET `System.Windows.Forms.Clipboard` 等直接 API 替代 PowerShell 子进程。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| D.1 | `src/utils/computerUse/executor.ts` | 剪贴板操作用直接 API 替代 PowerShell |
|
||||
| D.2 | 考虑驻留 PowerShell 进程 | 通过 stdin/stdout 交互,摊平启动成本 |
|
||||
|
||||
**剪贴板直接 API**(不需要 PowerShell 子进程):
|
||||
```powershell
|
||||
# 读:50ms → <1ms
|
||||
[System.Windows.Forms.Clipboard]::GetText()
|
||||
|
||||
# 写:50ms → <1ms
|
||||
[System.Windows.Forms.Clipboard]::SetText($text)
|
||||
|
||||
# 图片检测
|
||||
[System.Windows.Forms.Clipboard]::ContainsImage()
|
||||
```
|
||||
|
||||
### Phase E:`request_access` Windows 适配
|
||||
|
||||
**问题**:`request_access` 依赖 macOS bundleId 识别应用,Windows 没有这个概念。
|
||||
**方案**:在 Windows 上用 exe 路径 + 窗口标题替代 bundleId。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| E.1 | `packages/@ant/computer-use-mcp/src/toolCalls.ts` | `resolveRequestedApps` 在 Windows 上用 exe 路径匹配 |
|
||||
| E.2 | `packages/@ant/computer-use-mcp/src/sentinelApps.ts` | 增加 Windows 危险应用列表(cmd.exe, powershell.exe 等) |
|
||||
| E.3 | `packages/@ant/computer-use-mcp/src/deniedApps.ts` | 增加 Windows 浏览器/终端识别规则 |
|
||||
| E.4 | `src/utils/computerUse/hostAdapter.ts` | `ensureOsPermissions` Windows 上检查 UAC 状态 |
|
||||
|
||||
**Windows 应用标识映射**:
|
||||
```
|
||||
macOS bundleId → Windows 等价
|
||||
com.apple.Safari → C:\Program Files\...\msedge.exe(或窗口标题匹配)
|
||||
com.google.Chrome → chrome.exe
|
||||
com.apple.Terminal → WindowsTerminal.exe / cmd.exe
|
||||
```
|
||||
|
||||
### Phase F:全局热键(ESC 拦截)
|
||||
|
||||
**问题**:当前非 darwin 直接跳过 ESC 热键,用 Ctrl+C 替代。
|
||||
**方案**:用 `RegisterHotKey` 或 `SetWindowsHookEx(WH_KEYBOARD_LL)` 实现。
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| F.1 | `src/utils/computerUse/escHotkey.ts` | Windows 分支:RegisterHotKey 注册 ESC |
|
||||
|
||||
**优先级低**——当前 Ctrl+C fallback 可用,ESC 热键是体验优化。
|
||||
|
||||
## 5. 执行优先级
|
||||
|
||||
```
|
||||
Phase A: 窗口绑定截图 ← P0 核心需求,解决"操作其他界面"
|
||||
Phase B: UI Automation ← P0 核心能力,AI 理解 UI 结构
|
||||
Phase C: OCR ← P1 增值能力,AI 读屏幕文字
|
||||
Phase D: 性能优化 ← P1 体验优化,高频操作提速
|
||||
Phase E: request_access 适配 ← P1 功能完整性,权限模型适配
|
||||
Phase F: ESC 热键 ← P2 体验优化,可后做
|
||||
```
|
||||
|
||||
## 6. 每个 Phase 的改动量估算
|
||||
|
||||
| Phase | 新增文件 | 修改文件 | 新增代码行 | 风险 |
|
||||
|-------|---------|---------|-----------|------|
|
||||
| A 窗口截图 | 2 | 1 | ~200 | 低 |
|
||||
| B UI Automation | 1 | 1 | ~300 | 中 |
|
||||
| C OCR | 1 | 1 | ~150 | 低 |
|
||||
| D 性能优化 | 0 | 2 | ~50 | 低 |
|
||||
| E request_access | 0 | 3 | ~100 | 中 |
|
||||
| F ESC 热键 | 0 | 1 | ~50 | 低 |
|
||||
| **总计** | **4** | **9** | **~850** | — |
|
||||
|
||||
## 7. 不动的文件
|
||||
|
||||
- `backends/darwin.ts`(两个包都不动)
|
||||
- `backends/linux.ts`(两个包都不动)
|
||||
- `src/utils/computerUse/` 中 macOS 相关代码路径不动
|
||||
- `packages/@ant/computer-use-mcp/src/` 中已复制的参考项目代码不动(只追加 Windows 工具)
|
||||
|
||||
## 8. 与 macOS/Linux 方案的对比
|
||||
|
||||
| 能力 | macOS | Windows (增强后) | Linux |
|
||||
|------|-------|-----------------|-------|
|
||||
| 截图方式 | SCContentFilter (per-app) | **PrintWindow (per-window)** | scrot (全屏/区域) |
|
||||
| UI 结构 | Accessibility API | **UI Automation** | 无 |
|
||||
| OCR | 无内置 | **Windows.Media.Ocr** | 无内置 |
|
||||
| 键鼠 | CGEvent + enigo | SendInput + keybd_event | xdotool |
|
||||
| 窗口管理 | NSWorkspace | **EnumWindows + Win32** | wmctrl |
|
||||
| 剪贴板 | pbcopy/pbpaste | **Clipboard 直接 API** | xclip |
|
||||
| ESC 热键 | CGEventTap | RegisterHotKey | 无 |
|
||||
| 应用标识 | bundleId | exe 路径 + 窗口标题 | /proc + wmctrl |
|
||||
|
||||
**Windows 增强后将在 UI Automation 和 OCR 方面超过 macOS 方案**——这两项 macOS 原始实现也没有(Anthropic 用的是截图 + Claude 视觉理解,没有结构化 UI 数据)。
|
||||
197
docs/features/computer-use.md
Normal file
197
docs/features/computer-use.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Computer Use — macOS / Windows / Linux 跨平台实施计划
|
||||
|
||||
更新时间:2026-04-03
|
||||
参考项目:`E:\源码\claude-code-source-main\claude-code-source-main`
|
||||
|
||||
## 1. 现状
|
||||
|
||||
参考项目的 Computer Use **仅支持 macOS**——从入口到底层全部写死 darwin。我们的项目在 Phase 1-3 中已经完成了:
|
||||
|
||||
- ✅ `@ant/computer-use-mcp` stub 替换为完整实现(12 文件)
|
||||
- ✅ `@ant/computer-use-input` 拆为 dispatcher + backends(darwin + win32)
|
||||
- ✅ `@ant/computer-use-swift` 拆为 dispatcher + backends(darwin + win32)
|
||||
- ✅ `CHICAGO_MCP` 编译开关已开
|
||||
- ❌ `src/` 层有 6 处 macOS 硬编码阻塞
|
||||
|
||||
## 2. 阻塞点全景
|
||||
|
||||
### 2.1 入口层
|
||||
|
||||
| # | 文件:行号 | 阻塞代码 | 影响 |
|
||||
|---|----------|---------|------|
|
||||
| 1 | `src/main.tsx:1605` | `getPlatform() === 'macos'` | 整个 CU 初始化被跳过 |
|
||||
|
||||
### 2.2 加载层
|
||||
|
||||
| # | 文件:行号 | 阻塞代码 | 影响 |
|
||||
|---|----------|---------|------|
|
||||
| 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 特有依赖
|
||||
|
||||
| # | 文件:行号 | 依赖 | 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:直接 granted;Linux:检查 xdotool |
|
||||
| 8 | `common.ts:56` | 平台标识 | `platform: 'darwin'` 硬编码 | 动态获取 |
|
||||
| 9 | `executor.ts:180` | 粘贴快捷键 | `command+v` | Win/Linux:`ctrl+v` |
|
||||
|
||||
### 2.4 缺失的 Linux 后端
|
||||
|
||||
| 包 | macOS | Windows | Linux |
|
||||
|---|-------|---------|-------|
|
||||
| `computer-use-input/backends/` | ✅ darwin.ts | ✅ win32.ts | ❌ 需新建 linux.ts |
|
||||
| `computer-use-swift/backends/` | ✅ darwin.ts | ✅ win32.ts | ❌ 需新建 linux.ts |
|
||||
|
||||
## 3. 每个平台的能力依赖
|
||||
|
||||
### 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(截图 + 应用管理)
|
||||
|
||||
| 功能 | 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 层
|
||||
|
||||
| 功能 | 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` 编译开关
|
||||
|
||||
### Phase 2:移除 6 处 macOS 硬编码(解锁 macOS + Windows)
|
||||
|
||||
**改动原则:macOS 代码路径不变,只在每处 darwin 守卫后加 win32/linux 分支。**
|
||||
|
||||
| 步骤 | 文件 | 改动 |
|
||||
|------|------|------|
|
||||
| 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/pbpaste,win32→PowerShell Get/Set-Clipboard,linux→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 后端
|
||||
|
||||
| 步骤 | 文件 | 内容 |
|
||||
|------|------|------|
|
||||
| 3.1 | `packages/@ant/computer-use-input/src/backends/linux.ts` | xdotool 键鼠(mousemove/click/key/type/getactivewindow) |
|
||||
| 3.2 | `packages/@ant/computer-use-swift/src/backends/linux.ts` | scrot/grim 截图 + xrandr 显示器 + wmctrl 窗口管理 |
|
||||
| 3.3 | `packages/@ant/computer-use-input/src/index.ts` | dispatcher 加 `case 'linux'` |
|
||||
| 3.4 | `packages/@ant/computer-use-swift/src/index.ts` | dispatcher 加 `case 'linux'` |
|
||||
|
||||
### Phase 4:验证
|
||||
|
||||
| 测试项 | macOS | Windows | Linux |
|
||||
|--------|-------|---------|-------|
|
||||
| build 成功 | ✅ | 验证 | 验证 |
|
||||
| MCP 工具列表非空 | 验证 | 验证 | 验证 |
|
||||
| 鼠标移动 | 验证 | ✅ 已通过 | 验证 |
|
||||
| 截图 | 验证 | ✅ 已通过 | 验证 |
|
||||
| 键盘输入 | 验证 | 验证 | 验证 |
|
||||
| 前台窗口 | 验证 | ✅ 已通过 | 验证 |
|
||||
| 剪贴板 | 验证 | 验证 | 验证 |
|
||||
|
||||
## 5. 文件改动总览
|
||||
|
||||
### 不动的文件(14 个)
|
||||
|
||||
`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`(两个包都不动)
|
||||
|
||||
### 改 src/ 的文件(8 个)
|
||||
|
||||
| 文件 | 改动量 | 风险 |
|
||||
|------|--------|------|
|
||||
| `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 个)
|
||||
|
||||
| 文件 | 行数估算 |
|
||||
|------|---------|
|
||||
| `packages/@ant/computer-use-input/src/backends/linux.ts` | ~150 行 |
|
||||
| `packages/@ant/computer-use-swift/src/backends/linux.ts` | ~200 行 |
|
||||
|
||||
## 6. Linux 依赖工具
|
||||
|
||||
| 工具 | 用途 | 安装命令(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)。初期可先只支持 X11,Wayland 标记为 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 3(Linux 后端)
|
||||
├── 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 完成后三平台全部可用。
|
||||
Reference in New Issue
Block a user