Skip to content

Commit 650dbec

Browse files
unraidclaude
andcommitted
feat: enable Computer Use with Windows support
Phase 1: Replace @ant/computer-use-mcp stub with full implementation (12 files, 6517 lines from reference project). Phase 2-3: Refactor @ant/computer-use-input and @ant/computer-use-swift from single-file to dispatcher + backends/ architecture: - backends/darwin.ts — existing macOS AppleScript (unchanged logic) - backends/win32.ts — new Windows PowerShell (SetCursorPos, SendInput, CopyFromScreen, GetForegroundWindow) Add CHICAGO_MCP to default build features. Verified on Windows x64: mouse control, dual-monitor detection, full-screen screenshot, foreground app info, running process list. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 465e9f0 commit 650dbec

24 files changed

Lines changed: 7819 additions & 737 deletions

File tree

DEV-LOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# DEV-LOG
22

3+
## Enable Computer Use with Windows support (2026-04-03)
4+
5+
恢复 Computer Use 屏幕操控功能,并新增 Windows 支持(参考项目仅 macOS)。
6+
7+
**Phase 1 — MCP server stub 替换:**
8+
9+
从参考项目复制 `@ant/computer-use-mcp` 完整实现(12 文件,6517 行),替换原 stub。
10+
11+
**Phase 2 — input 包平台架构:**
12+
13+
`@ant/computer-use-input` 从单文件拆为 dispatcher + backends 架构:
14+
- `index.ts` → dispatcher(按 platform 选后端)
15+
- `types.ts` → 共享 InputBackend 接口
16+
- `backends/darwin.ts` → 原有 macOS AppleScript 实现(原样拆出)
17+
- `backends/win32.ts` → 新增 Windows PowerShell 实现(SetCursorPos/SendInput/keybd_event)
18+
19+
**Phase 3 — swift 包平台架构:**
20+
21+
`@ant/computer-use-swift` 同样拆为 dispatcher + backends:
22+
- `backends/darwin.ts` → 原有 macOS screencapture 实现
23+
- `backends/win32.ts` → 新增 Windows PowerShell 实现(CopyFromScreen/GetProcess/Win32 API)
24+
25+
**编译开关:** `DEFAULT_FEATURES` + `DEFAULT_BUILD_FEATURES``"CHICAGO_MCP"`
26+
27+
**验证结果(Windows x64):**
28+
- `isSupported: true`
29+
- 鼠标移动/画圆 ✅
30+
- 前台窗口信息 ✅
31+
- 双显示器检测 ✅
32+
- 全屏截图 2560x1440 ✅
33+
- 运行中应用列表 ✅
34+
35+
---
36+
337
## Enable Remote Control / BRIDGE_MODE (2026-04-03)
438

539
**PR**: [claude-code-best/claude-code#60](https://github.com/claude-code-best/claude-code/pull/60)

build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ rmSync(outdir, { recursive: true, force: true });
1010

1111
// Default features that match the official CLI build.
1212
// Additional features can be enabled via FEATURE_<NAME>=1 env vars.
13-
const DEFAULT_BUILD_FEATURES = ["AGENT_TRIGGERS_REMOTE"];
13+
const DEFAULT_BUILD_FEATURES = ["AGENT_TRIGGERS_REMOTE", "CHICAGO_MCP"];
1414

1515
// Collect FEATURE_* env vars → Bun.build features
1616
const envFeatures = Object.keys(process.env)

docs/features/computer-use.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Computer Use — 恢复 + Windows 支持计划
2+
3+
更新时间:2026-04-03
4+
参考项目:`E:\源码\claude-code-source-main\claude-code-source-main`
5+
6+
## 1. 目标
7+
8+
让 Computer Use(屏幕操控)功能在 macOS 和 Windows 上都能工作。
9+
10+
## 2. 涉及的 3 个包
11+
12+
```
13+
feature('CHICAGO_MCP')
14+
15+
16+
@ant/computer-use-mcp ← MCP server + 工具定义(当前 STUB)
17+
├── @ant/computer-use-input ← 键鼠模拟(当前仅 macOS AppleScript)
18+
└── @ant/computer-use-swift ← 截图 + 应用管理(当前仅 macOS AppleScript)
19+
```
20+
21+
|| 当前状态 | 需要做什么 |
22+
|---|---------|----------|
23+
| `computer-use-mcp` | stub(返回空工具/null server) | 从参考项目复制完整实现(12 文件,6517 行) |
24+
| `computer-use-input` | macOS AppleScript 实现(183 行) | 保留 macOS,新增 Windows PowerShell 后端 |
25+
| `computer-use-swift` | macOS AppleScript 实现(388 行) | 保留 macOS,新增 Windows PowerShell 后端 |
26+
27+
## 3. 文件架构设计
28+
29+
### 3.1 `@ant/computer-use-input` — 键鼠模拟
30+
31+
**当前**:所有代码在 `src/index.ts` 一个文件里,macOS only。
32+
33+
**改为**
34+
35+
```
36+
packages/@ant/computer-use-input/src/
37+
├── index.ts ← dispatcher:按 platform 选后端,导出统一 API
38+
├── backends/
39+
│ ├── darwin.ts ← 现有 AppleScript/JXA 实现(从 index.ts 拆出,不改逻辑)
40+
│ └── win32.ts ← 新增 PowerShell 实现
41+
└── types.ts ← 共享类型定义(从 index.ts 拆出)
42+
```
43+
44+
**`index.ts`(dispatcher)**
45+
```typescript
46+
import type { InputBackend } from './types.js'
47+
48+
function loadBackend(): InputBackend | null {
49+
switch (process.platform) {
50+
case 'darwin':
51+
return require('./backends/darwin.js')
52+
case 'win32':
53+
return require('./backends/win32.js')
54+
default:
55+
return null
56+
}
57+
}
58+
59+
const backend = loadBackend()
60+
export const isSupported = backend !== null
61+
62+
export const moveMouse = backend?.moveMouse ?? unsupported
63+
export const key = backend?.key ?? unsupported
64+
export const keys = backend?.keys ?? unsupported
65+
// ... 其余导出
66+
```
67+
68+
**`types.ts`**
69+
```typescript
70+
export interface FrontmostAppInfo {
71+
bundleId: string // macOS: bundle ID, Windows: exe path
72+
appName: string
73+
}
74+
75+
export interface InputBackend {
76+
moveMouse(x: number, y: number, animated: boolean): Promise<void>
77+
key(key: string, action: 'press' | 'release'): Promise<void>
78+
keys(parts: string[]): Promise<void>
79+
mouseLocation(): Promise<{ x: number; y: number }>
80+
mouseButton(button: 'left' | 'right' | 'middle', action: 'click' | 'press' | 'release', count?: number): Promise<void>
81+
mouseScroll(amount: number, direction: 'vertical' | 'horizontal'): Promise<void>
82+
typeText(text: string): Promise<void>
83+
getFrontmostAppInfo(): FrontmostAppInfo | null
84+
}
85+
```
86+
87+
**`backends/darwin.ts`**:现有 `index.ts` 中的 macOS 实现原样拆出,不改一行逻辑。
88+
89+
**`backends/win32.ts`**:PowerShell 实现,已验证可行的 API:
90+
91+
| 函数 | PowerShell 方案 | 已验证 |
92+
|------|----------------|--------|
93+
| `moveMouse` | `SetCursorPos` Win32 P/Invoke | ✅ 画圆测试通过 |
94+
| `mouseButton` | `SendInput` MOUSEEVENTF_*DOWN/*UP | ✅ 类型加载成功 |
95+
| `mouseScroll` | `SendInput` MOUSEEVENTF_WHEEL/HWHEEL | ✅ 滚轮测试通过 |
96+
| `mouseLocation` | `GetCursorPos` Win32 P/Invoke | ✅ 坐标读取成功 |
97+
| `key` | `keybd_event` P/Invoke | ✅ 类型加载成功 |
98+
| `keys` | `keybd_event` 组合(modifier down → key → modifier up) ||
99+
| `typeText` | `SendKeys.SendWait()` | ✅ API 可用 |
100+
| `getFrontmostAppInfo` | `GetForegroundWindow` + `GetWindowThreadProcessId` | ✅ 返回进程名+路径 |
101+
102+
**Win32 实现要点**
103+
- 所有 P/Invoke 的 `Add-Type` 代码编译一次,缓存在模块级变量中,避免每次调用重复编译
104+
- PowerShell 每次启动约 273ms;考虑用 `Bun.spawn` 启动一个长期驻留的 PowerShell 进程,通过 stdin/stdout 交互,摊平启动成本
105+
106+
### 3.2 `@ant/computer-use-swift` — 截图 + 应用管理
107+
108+
**当前**:所有代码在 `src/index.ts` 一个文件里,macOS only。
109+
110+
**改为**
111+
112+
```
113+
packages/@ant/computer-use-swift/src/
114+
├── index.ts ← dispatcher:按 platform 选后端,导出 ComputerUseAPI 类
115+
├── backends/
116+
│ ├── darwin.ts ← 现有 AppleScript/screencapture 实现(拆出)
117+
│ └── win32.ts ← 新增 PowerShell 实现
118+
└── types.ts ← 共享类型(DisplayGeometry, AppInfo, ScreenshotResult 等)
119+
```
120+
121+
**`backends/win32.ts`** 需要实现的函数:
122+
123+
| 函数 | PowerShell 方案 | 已验证 |
124+
|------|----------------|--------|
125+
| `captureExcluding()` | `Graphics.CopyFromScreen` 全屏 → PNG → base64 | ✅ 191KB 截图成功 |
126+
| `captureRegion(x,y,w,h)` | `Graphics.CopyFromScreen` 指定区域 | ✅ 区域截图成功 |
127+
| `prepareDisplay()` | `Screen.AllScreens` | ✅ 检测到双显示器 |
128+
| `apps.listRunning()` | `Get-Process` 带 MainWindowTitle | ✅ 返回进程列表 |
129+
| `apps.open(name)` | `Start-Process` | 标准 API |
130+
| `getFrontmostAppInfo()` | `GetForegroundWindow` + `GetWindowThreadProcessId` ||
131+
| `findWindowDisplays()` | `EnumWindows` + `MonitorFromWindow` | 需实现 |
132+
133+
### 3.3 `@ant/computer-use-mcp` — MCP Server
134+
135+
**纯 stub 替换**,与 chrome-mcp 同模式。从参考项目复制 12 个文件:
136+
137+
```
138+
packages/@ant/computer-use-mcp/src/
139+
├── index.ts ← 覆盖 stub
140+
├── types.ts ← 覆盖(参考项目版本更完整)
141+
├── sentinelApps.ts ← 覆盖(参考项目版本更完整)
142+
├── mcpServer.ts ← 新增
143+
├── executor.ts ← 新增
144+
├── toolCalls.ts ← 新增(3649 行,最大文件)
145+
├── tools.ts ← 新增
146+
├── deniedApps.ts ← 新增
147+
├── keyBlocklist.ts ← 新增
148+
├── imageResize.ts ← 新增
149+
├── pixelCompare.ts ← 新增
150+
└── subGates.ts ← 新增
151+
```
152+
153+
## 4. 执行步骤
154+
155+
### Phase 1:恢复 MCP server(标准 stub 替换,不涉及 Windows)
156+
157+
| 步骤 | 操作 | 文件 |
158+
|------|------|------|
159+
| 1.1 | 从参考项目复制 computer-use-mcp 完整实现 | `packages/@ant/computer-use-mcp/src/` 12 文件 |
160+
| 1.2 | `DEFAULT_FEATURES``"CHICAGO_MCP"` | `scripts/dev.ts` + `build.ts` |
161+
| 1.3 | 验证 build 成功 | `bun run build` |
162+
| 1.4 | 验证 macOS 现有功能不受影响 | 非 macOS 可跳过 |
163+
164+
### Phase 2:拆分 input 包为平台后端架构
165+
166+
| 步骤 | 操作 | 文件 |
167+
|------|------|------|
168+
| 2.1 | 创建 `types.ts`,定义 `InputBackend` 接口 | 新增 |
169+
| 2.2 | 现有 `index.ts` macOS 代码拆到 `backends/darwin.ts` | 拆分,不改逻辑 |
170+
| 2.3 | `index.ts` 改为 dispatcher | 重写 |
171+
| 2.4 | 验证 macOS 功能不变(如有 macOS 环境) ||
172+
| 2.5 | 编写 `backends/win32.ts` PowerShell 实现 | 新增 |
173+
| 2.6 | Windows 上验证 8 个函数 | 逐个测试 |
174+
175+
### Phase 3:拆分 swift 包为平台后端架构
176+
177+
| 步骤 | 操作 | 文件 |
178+
|------|------|------|
179+
| 3.1 | 创建 `types.ts`,定义共享类型 | 新增 |
180+
| 3.2 | 现有 `index.ts` macOS 代码拆到 `backends/darwin.ts` | 拆分,不改逻辑 |
181+
| 3.3 | `index.ts` 改为 dispatcher | 重写 |
182+
| 3.4 | 编写 `backends/win32.ts` PowerShell 实现 | 新增 |
183+
| 3.5 | Windows 上验证截图、应用管理 | 逐个测试 |
184+
185+
### Phase 4:集成验证
186+
187+
| 步骤 | 操作 |
188+
|------|------|
189+
| 4.1 | `bun run build` 成功 |
190+
| 4.2 | Windows: Computer Use 工具列表非空 |
191+
| 4.3 | Windows: 截图、鼠标移动、键盘输入端到端测试 |
192+
| 4.4 | DEV-LOG.md 追加章节 |
193+
| 4.5 | 提交 PR |
194+
195+
## 5. 文件改动总览
196+
197+
### Phase 1(stub 替换)
198+
199+
| 操作 | 文件 | 说明 |
200+
|------|------|------|
201+
| 覆盖 | `packages/@ant/computer-use-mcp/src/index.ts` | stub → 完整导出 |
202+
| 覆盖 | `packages/@ant/computer-use-mcp/src/types.ts` | 补全类型 |
203+
| 覆盖 | `packages/@ant/computer-use-mcp/src/sentinelApps.ts` | 补全 |
204+
| 新增 | `packages/@ant/computer-use-mcp/src/` 其余 9 文件 | 参考项目复制 |
205+
| 修改 | `scripts/dev.ts` + `build.ts` |`"CHICAGO_MCP"` |
206+
207+
### Phase 2(input 平台架构)
208+
209+
| 操作 | 文件 | 说明 |
210+
|------|------|------|
211+
| 新增 | `packages/@ant/computer-use-input/src/types.ts` | InputBackend 接口 |
212+
| 拆分 | `packages/@ant/computer-use-input/src/backends/darwin.ts` | 从 index.ts 拆出 |
213+
| 重写 | `packages/@ant/computer-use-input/src/index.ts` | dispatcher |
214+
| 新增 | `packages/@ant/computer-use-input/src/backends/win32.ts` | PowerShell 键鼠 |
215+
216+
### Phase 3(swift 平台架构)
217+
218+
| 操作 | 文件 | 说明 |
219+
|------|------|------|
220+
| 新增 | `packages/@ant/computer-use-swift/src/types.ts` | 共享类型 |
221+
| 拆分 | `packages/@ant/computer-use-swift/src/backends/darwin.ts` | 从 index.ts 拆出 |
222+
| 重写 | `packages/@ant/computer-use-swift/src/index.ts` | dispatcher |
223+
| 新增 | `packages/@ant/computer-use-swift/src/backends/win32.ts` | PowerShell 截图+应用 |
224+
225+
## 6. 性能预期
226+
227+
| 操作 | macOS (AppleScript) | Windows (PowerShell) | 原生 .node |
228+
|------|--------------------|--------------------|-----------|
229+
| 鼠标移动 | ~50ms | ~273ms(首次),可优化到 ~30ms(驻留进程) | ~1ms |
230+
| 键盘输入 | ~50ms | ~273ms,同上 | ~1ms |
231+
| 截图 | ~200ms | ~273ms | ~50ms |
232+
| 前台窗口 | ~100ms | ~273ms,同上 | ~1ms |
233+
234+
**优化方向**:启动一个长驻 PowerShell 进程,通过 stdin 发送命令、stdout 读取结果。可将每次调用延迟从 273ms 降到 ~30ms。此优化可在基础功能验证后的 Phase 5 中实施。
235+
236+
## 7. 不改动的文件
237+
238+
- `src/utils/computerUse/` 下所有文件 — 已与参考项目一致
239+
- `src/services/mcp/client.ts` — 已包含 CHICAGO_MCP 门控逻辑
240+
- `src/commands.ts` — 无需改动
241+
242+
## 8. 运行时前置条件
243+
244+
| 条件 | macOS | Windows |
245+
|------|-------|---------|
246+
| feature flag | `CHICAGO_MCP` ||
247+
| GrowthBook | `tengu_malort_pedway` enabled | 同(需绕过或设默认 true) |
248+
| 系统权限 | Accessibility 权限 | 无特殊权限 |
249+
| 外部依赖 | 无(osascript 内置) | 无(PowerShell 内置) |

0 commit comments

Comments
 (0)