Files
qwen-code/packages/browser-use/build.mjs
T
顾盼 a791e47a54 feat(cua): streamline computer use and port native reliability fixes (#14846)
* feat(cua): preload the JavaScript computer use runtime

* refactor(cua): remove the native Wayland backend

* feat(cua): move app computer use into the driver

* feat(cua): preserve background delivery and port platform fixes

* feat(cua): add explicit desktop input and browser runtime facade

* feat(cua): package the unified 0.26.0 computer use runtime

* fix(cua): finalize cross-platform native reliability

* fix(cua): isolate runtime releases from CLI versioning

* fix(cua): keep Electron out of root workspace installs

* fix(cua): synchronize consumers and async cleanup tests

* fix(browser): migrate smoke to preloaded cua runtime

* docs(cua): document MCP setup for Qwen Code Claude Code and Codex
2026-10-21 14:03:31 +08:00

93 lines
3.4 KiB
JavaScript

/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { chmodSync, readFileSync, rmSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { build } from 'esbuild';
const root = path.dirname(fileURLToPath(import.meta.url));
const dist = path.join(root, 'dist');
// The SDK checks that the playwright-core it resolves is the pinned one, so a
// runtime missing its bundled copy cannot silently load another install.
const manifest = JSON.parse(
readFileSync(path.join(root, 'package.json'), 'utf8'),
);
const define = {
__QWEN_PLAYWRIGHT_CORE_VERSION__: JSON.stringify(
manifest.dependencies['playwright-core'],
),
};
const nodeBanner =
"import { createRequire as __qwenCreateRequire } from 'node:module'; import { fileURLToPath as __qwenFileURLToPath } from 'node:url'; import { dirname as __qwenDirname } from 'node:path'; const require = __qwenCreateRequire(import.meta.url); const __filename = __qwenFileURLToPath(import.meta.url); const __dirname = __qwenDirname(__filename);";
// The bundled skill imports dist/index.js (staged as runtime/index.js) from
// inside the node_repl kernel: packages/node-repl/src/runtime/module-loader.mjs
// compiles absolute-path imports as vm.SourceTextModule in the kernel's
// untrusted vm context, which is built from Object.create(null), never defines
// a `process` global, and denies the `node:process` import specifier. The SDK
// reads process.env/process.platform, so bind `process` through createRequire,
// the one route the kernel leaves open. The load check at the bottom of this
// file runs in Node's main realm, where `process` is always a global, so it
// cannot detect this binding going missing; src/runtime-kernel.test.ts
// imports the SDK through the real kernel for that.
const kernelBanner =
"import { createRequire as __qwenCreateRequire } from 'node:module'; const process = __qwenCreateRequire(import.meta.url)('node:process');";
rmSync(dist, { recursive: true, force: true });
await build({
absWorkingDir: root,
entryPoints: {
index: 'src/index.ts',
},
outdir: dist,
bundle: true,
platform: 'node',
target: 'node22',
format: 'esm',
banner: {
js: kernelBanner,
},
packages: 'bundle',
define,
external: ['playwright-core', 'playwright-core/*'],
});
await build({
absWorkingDir: root,
entryPoints: {
'native-host': 'src/bridge/native-host/index.ts',
'scripts/native-host-setup': 'scripts/native-host-setup.ts',
'scripts/managed-chrome': 'scripts/managed-chrome.ts',
'scripts/managed-chrome-preflight': 'scripts/managed-chrome-preflight.ts',
'scripts/smoke-qwen-saucedemo': 'scripts/smoke-qwen-saucedemo.ts',
},
outdir: dist,
bundle: true,
platform: 'node',
target: 'node22',
format: 'esm',
banner: {
js: nodeBanner,
},
packages: 'bundle',
define,
external: ['playwright-core', 'playwright-core/*'],
loader: { '.wasm': 'binary' },
});
for (const executable of [
path.join(dist, 'native-host.js'),
path.join(dist, 'scripts/native-host-setup.js'),
]) {
chmodSync(executable, 0o755);
}
// esbuild only proves the bundle parses; a load-time failure (a duplicate
// top-level binding, an unresolved external) would otherwise surface first in
// the Node kernel that imports the published artifact.
await import(pathToFileURL(path.join(dist, 'index.js')).href);