#!/usr/bin/env tsx /** * Regenerate packages/core/src/tools/computer-use/schemas.ts from a live * cua-driver MCP server (`cua-driver mcp`). * * Usage: * npx tsx scripts/sync-computer-use-schemas.ts [binaryPath] * * Defaults to the pinned cua-driver binary under `~/.qwen/computer-use/` * (resolved from CUA_DRIVER_VERSION in constants.ts) — i.e. the binary that * gets installed the first time Computer Use runs. Pass an explicit path to * point at a different build. * * Bumping the pin is a procedure documented in constants.ts — read that * JSDoc first. */ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { writeFile } from 'node:fs/promises'; import { homedir } from 'node:os'; import { resolve } from 'node:path'; import { CUA_DRIVER_VERSION, binaryPath, } from '../packages/core/src/tools/computer-use/constants.js'; // cua-driver 0.5.2 advertises 35 tools. A drift here just means the upstream // surface changed — warn (so a bump is reviewed) but don't fail the sync. const EXPECTED_TOOL_COUNT = 35; async function main(): Promise { // Default to the pinned, locally-installed binary; allow an explicit override. const binary = process.argv[2] ?? binaryPath(homedir()); const transport = new StdioClientTransport({ command: binary, args: ['mcp'], }); const client = new Client( { name: 'qwen-code-schema-sync', version: '1.0.0' }, { capabilities: {} }, ); await client.connect(transport); const result = await client.listTools(); await client.close(); if (result.tools.length !== EXPECTED_TOOL_COUNT) { process.stderr.write( `WARNING: cua-driver v${CUA_DRIVER_VERSION} returned ${result.tools.length} tools, expected ${EXPECTED_TOOL_COUNT}. Review the diff before committing.\n`, ); } const schemas: Record< string, { description: string; parameterSchema: unknown } > = {}; for (const tool of result.tools) { schemas[tool.name] = { description: tool.description ?? '', parameterSchema: tool.inputSchema ?? { type: 'object', properties: {} }, }; } const out = `/** * @license * Copyright 2025 Qwen Team * SPDX-License-Identifier: Apache-2.0 */ /** * Hardcoded schemas for the cua-driver computer-use tools. * * Pinned to: cua-driver-rs v${CUA_DRIVER_VERSION} (see CUA_DRIVER_VERSION in constants.ts). * * Generated from the live \`cua-driver mcp\` \`tools/list\` output — the FULL * tool surface cua-driver advertises (no curation). Exposing the complete set * (including page/CDP, cursor, session, recording, config, kill_app, …) so the * model has every capability cua-driver actually provides. * * Regenerated by scripts/sync-computer-use-schemas.ts — do not hand-edit. */ export interface ComputerUseToolSchema { description: string; parameterSchema: Record; } export const COMPUTER_USE_TOOL_NAMES = ${JSON.stringify( result.tools.map((t) => t.name), null, 2, )} as const; export type ComputerUseToolName = (typeof COMPUTER_USE_TOOL_NAMES)[number]; export const COMPUTER_USE_SCHEMAS: Record = ${JSON.stringify( schemas, null, 2, )}; `; const target = resolve('packages/core/src/tools/computer-use/schemas.ts'); await writeFile(target, out, 'utf8'); process.stdout.write( `Wrote ${result.tools.length} cua-driver tool schemas to ${target}\n`, ); } main().catch((err) => { process.stderr.write(`Schema sync failed: ${err}\n`); process.exit(1); });