feat: 升级 @ant/computer-use-mcp — 类型安全 stub + sentinel apps
- types.ts: 替换所有 any 为真实类型 (CoordinateMode, CuSubGates, Logger, GrantFlags, CuPermissionRequest/Response, ComputerUseHostAdapter) - index.ts: 所有导出类型化 (DisplayGeometry, FrontmostApp, InstalledApp, RunningApp, ScreenshotResult, CuCallToolResult 等); targetImageSize() 实现真实缩放逻辑; bindSessionContext() 返回类型正确的空调度器 - sentinelApps.ts: 添加 10 个 macOS 敏感应用 (Terminal, iTerm2, Finder, System Preferences 等) 及其分类 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
975b4876cc
commit
b51b2d7675
4
TODO.md
4
TODO.md
@ -10,8 +10,8 @@
|
|||||||
- [x] `color-diff-napi` — 颜色差异计算 NAPI 模块 (纯 TS 实现)
|
- [x] `color-diff-napi` — 颜色差异计算 NAPI 模块 (纯 TS 实现)
|
||||||
- [x] `image-processor-napi` — 图像处理 NAPI 模块 (sharp + osascript 剪贴板)
|
- [x] `image-processor-napi` — 图像处理 NAPI 模块 (sharp + osascript 剪贴板)
|
||||||
|
|
||||||
<!-- - [ ] `@ant/computer-use-swift` — Computer Use Swift 原生模块
|
<!-- - [ ] `@ant/computer-use-swift` — Computer Use Swift 原生模块 -->
|
||||||
- [ ] `@ant/computer-use-mcp` — Computer Use MCP 服务 -->
|
- [x] `@ant/computer-use-mcp` — Computer Use MCP 服务 (类型安全 stub + sentinel apps + targetImageSize)
|
||||||
- [x] `@ant/computer-use-input` — Computer Use 输入模块 (macOS AppleScript/JXA 实现)
|
- [x] `@ant/computer-use-input` — Computer Use 输入模块 (macOS AppleScript/JXA 实现)
|
||||||
<!-- - [ ] `@ant/claude-for-chrome-mcp` — Chrome MCP 扩展 -->
|
<!-- - [ ] `@ant/claude-for-chrome-mcp` — Chrome MCP 扩展 -->
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +1,163 @@
|
|||||||
export const API_RESIZE_PARAMS: any = {}
|
/**
|
||||||
|
* @ant/computer-use-mcp — Stub 实现
|
||||||
|
*
|
||||||
|
* 提供类型安全的 stub,所有函数返回合理的默认值。
|
||||||
|
* 在 feature('CHICAGO_MCP') = false 时不会被实际调用,
|
||||||
|
* 但确保 import 不报错且类型正确。
|
||||||
|
*/
|
||||||
|
|
||||||
export class ComputerExecutor {}
|
import type {
|
||||||
|
ComputerUseHostAdapter,
|
||||||
|
CoordinateMode,
|
||||||
|
GrantFlags,
|
||||||
|
Logger,
|
||||||
|
} from './types'
|
||||||
|
|
||||||
export type ComputerUseSessionContext = any
|
// Re-export types from types.ts
|
||||||
export type CuCallToolResult = any
|
export type { CoordinateMode, Logger } from './types'
|
||||||
export type CuPermissionRequest = any
|
export type {
|
||||||
export type CuPermissionResponse = any
|
ComputerUseConfig,
|
||||||
export const DEFAULT_GRANT_FLAGS: any = {}
|
ComputerUseHostAdapter,
|
||||||
export type DisplayGeometry = any
|
CuPermissionRequest,
|
||||||
export type FrontmostApp = any
|
CuPermissionResponse,
|
||||||
export type InstalledApp = any
|
CuSubGates,
|
||||||
export type ResolvePrepareCaptureResult = any
|
} from './types'
|
||||||
export type RunningApp = any
|
export { DEFAULT_GRANT_FLAGS } from './types'
|
||||||
export type ScreenshotDims = any
|
|
||||||
export type ScreenshotResult = any
|
|
||||||
|
|
||||||
export function bindSessionContext(..._args: any[]): any {
|
// ---------------------------------------------------------------------------
|
||||||
return null
|
// Types (defined here for callers that import from the main entry)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export interface DisplayGeometry {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
displayId?: number
|
||||||
|
originX?: number
|
||||||
|
originY?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildComputerUseTools(..._args: any[]): any[] {
|
export interface FrontmostApp {
|
||||||
|
bundleId: string
|
||||||
|
displayName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InstalledApp {
|
||||||
|
bundleId: string
|
||||||
|
displayName: string
|
||||||
|
path: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RunningApp {
|
||||||
|
bundleId: string
|
||||||
|
displayName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScreenshotResult {
|
||||||
|
base64: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ResolvePrepareCaptureResult = ScreenshotResult
|
||||||
|
|
||||||
|
export interface ScreenshotDims {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
displayWidth: number
|
||||||
|
displayHeight: number
|
||||||
|
displayId: number
|
||||||
|
originX: number
|
||||||
|
originY: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CuCallToolResultContent {
|
||||||
|
type: 'image' | 'text'
|
||||||
|
data?: string
|
||||||
|
mimeType?: string
|
||||||
|
text?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CuCallToolResult {
|
||||||
|
content: CuCallToolResultContent[]
|
||||||
|
telemetry: {
|
||||||
|
error_kind?: string
|
||||||
|
[key: string]: unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ComputerUseSessionContext = Record<string, unknown>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// API_RESIZE_PARAMS — 默认的截图缩放参数
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export const API_RESIZE_PARAMS = {
|
||||||
|
maxWidth: 1280,
|
||||||
|
maxHeight: 800,
|
||||||
|
maxPixels: 1280 * 800,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ComputerExecutor — stub class
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export class ComputerExecutor {
|
||||||
|
capabilities: Record<string, boolean> = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Functions — 返回合理默认值的 stub
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算目标截图尺寸。
|
||||||
|
* 在物理宽高和 API 限制之间取最优尺寸。
|
||||||
|
*/
|
||||||
|
export function targetImageSize(
|
||||||
|
physW: number,
|
||||||
|
physH: number,
|
||||||
|
_params?: typeof API_RESIZE_PARAMS,
|
||||||
|
): [number, number] {
|
||||||
|
const maxW = _params?.maxWidth ?? 1280
|
||||||
|
const maxH = _params?.maxHeight ?? 800
|
||||||
|
const scale = Math.min(1, maxW / physW, maxH / physH)
|
||||||
|
return [Math.round(physW * scale), Math.round(physH * scale)]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定会话上下文,返回工具调度函数。
|
||||||
|
* Stub 返回一个始终返回空结果的调度器。
|
||||||
|
*/
|
||||||
|
export function bindSessionContext(
|
||||||
|
_adapter: ComputerUseHostAdapter,
|
||||||
|
_coordinateMode: CoordinateMode,
|
||||||
|
_ctx: ComputerUseSessionContext,
|
||||||
|
): (name: string, args: unknown) => Promise<CuCallToolResult> {
|
||||||
|
return async (_name: string, _args: unknown) => ({
|
||||||
|
content: [],
|
||||||
|
telemetry: {},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建 Computer Use 工具定义列表。
|
||||||
|
* Stub 返回空数组(无工具)。
|
||||||
|
*/
|
||||||
|
export function buildComputerUseTools(
|
||||||
|
_capabilities?: Record<string, boolean>,
|
||||||
|
_coordinateMode?: CoordinateMode,
|
||||||
|
_installedAppNames?: string[],
|
||||||
|
): Array<{ name: string; description: string; inputSchema: Record<string, unknown> }> {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createComputerUseMcpServer(..._args: any[]): any {
|
/**
|
||||||
|
* 创建 Computer Use MCP server。
|
||||||
|
* Stub 返回 null(服务未启用)。
|
||||||
|
*/
|
||||||
|
export function createComputerUseMcpServer(
|
||||||
|
_adapter?: ComputerUseHostAdapter,
|
||||||
|
_coordinateMode?: CoordinateMode,
|
||||||
|
): null {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
export const targetImageSize: any = null
|
|
||||||
|
|||||||
@ -1,5 +1,32 @@
|
|||||||
export const sentinelApps: string[] = []
|
/**
|
||||||
|
* Sentinel apps — 需要特殊权限警告的应用列表
|
||||||
|
*
|
||||||
|
* 包含终端、文件管理器、系统设置等敏感应用。
|
||||||
|
* Computer Use 操作这些应用时会显示额外警告。
|
||||||
|
*/
|
||||||
|
|
||||||
export function getSentinelCategory(_appName: string): string | null {
|
type SentinelCategory = 'shell' | 'filesystem' | 'system_settings'
|
||||||
return null
|
|
||||||
|
const SENTINEL_MAP: Record<string, SentinelCategory> = {
|
||||||
|
// Shell / Terminal
|
||||||
|
'com.apple.Terminal': 'shell',
|
||||||
|
'com.googlecode.iterm2': 'shell',
|
||||||
|
'dev.warp.Warp-Stable': 'shell',
|
||||||
|
'io.alacritty': 'shell',
|
||||||
|
'com.github.wez.wezterm': 'shell',
|
||||||
|
'net.kovidgoyal.kitty': 'shell',
|
||||||
|
'co.zeit.hyper': 'shell',
|
||||||
|
|
||||||
|
// Filesystem
|
||||||
|
'com.apple.finder': 'filesystem',
|
||||||
|
|
||||||
|
// System Settings
|
||||||
|
'com.apple.systempreferences': 'system_settings',
|
||||||
|
'com.apple.SystemPreferences': 'system_settings',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sentinelApps: string[] = Object.keys(SENTINEL_MAP)
|
||||||
|
|
||||||
|
export function getSentinelCategory(bundleId: string): SentinelCategory | null {
|
||||||
|
return SENTINEL_MAP[bundleId] ?? null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,70 @@
|
|||||||
export type ComputerUseConfig = any
|
/**
|
||||||
export type ComputerUseHostAdapter = any
|
* @ant/computer-use-mcp — Types
|
||||||
export type CoordinateMode = any
|
*
|
||||||
export type CuPermissionRequest = any
|
* 从调用侧反推的真实类型定义,替代 any stub。
|
||||||
export type CuPermissionResponse = any
|
*/
|
||||||
export type CuSubGates = any
|
|
||||||
export const DEFAULT_GRANT_FLAGS: any = {}
|
export type CoordinateMode = 'pixels' | 'normalized'
|
||||||
export type Logger = any
|
|
||||||
|
export interface CuSubGates {
|
||||||
|
pixelValidation: boolean
|
||||||
|
clipboardPasteMultiline: boolean
|
||||||
|
mouseAnimation: boolean
|
||||||
|
hideBeforeAction: boolean
|
||||||
|
autoTargetDisplay: boolean
|
||||||
|
clipboardGuard: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Logger {
|
||||||
|
silly(message: string, ...args: unknown[]): void
|
||||||
|
debug(message: string, ...args: unknown[]): void
|
||||||
|
info(message: string, ...args: unknown[]): void
|
||||||
|
warn(message: string, ...args: unknown[]): void
|
||||||
|
error(message: string, ...args: unknown[]): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CuPermissionRequest {
|
||||||
|
apps: Array<{ bundleId: string; displayName: string }>
|
||||||
|
requestedFlags: GrantFlags
|
||||||
|
reason: string
|
||||||
|
tccState: { accessibility: boolean; screenRecording: boolean }
|
||||||
|
willHide: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GrantFlags {
|
||||||
|
clipboardRead: boolean
|
||||||
|
clipboardWrite: boolean
|
||||||
|
systemKeyCombos: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CuPermissionResponse {
|
||||||
|
granted: string[]
|
||||||
|
denied: string[]
|
||||||
|
flags: GrantFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_GRANT_FLAGS: GrantFlags = {
|
||||||
|
clipboardRead: false,
|
||||||
|
clipboardWrite: false,
|
||||||
|
systemKeyCombos: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComputerUseConfig {
|
||||||
|
coordinateMode: CoordinateMode
|
||||||
|
enabledTools: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComputerUseHostAdapter {
|
||||||
|
serverName: string
|
||||||
|
logger: Logger
|
||||||
|
executor: ComputerExecutor
|
||||||
|
ensureOsPermissions(): Promise<{ granted: true } | { granted: false; accessibility: boolean; screenRecording: boolean }>
|
||||||
|
isDisabled(): boolean
|
||||||
|
getSubGates(): CuSubGates
|
||||||
|
getAutoUnhideEnabled(): boolean
|
||||||
|
cropRawPatch?(base64: string, x: number, y: number, w: number, h: number): Promise<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComputerExecutor {
|
||||||
|
capabilities: Record<string, boolean>
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user