diff --git a/package-lock.json b/package-lock.json index 244ba80..6d01e86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "electron": "31.7.7", "electron-builder": "^26.15.7", "electron-vite": "^6.0.0", + "tsx": "^4.19.2", "typescript": "^5.7.2", "vite": "^7.1.0", "vitest": "^2.1.8" @@ -10775,6 +10776,25 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.23.15", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz", + "integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-fest": { "version": "0.13.1", "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.13.1.tgz", diff --git a/package.json b/package.json index c5b92a1..65468e4 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "preview": "electron-vite preview", "typecheck": "tsc --noEmit -p tsconfig.json", "check:deps": "node packages/rpa-core/scripts/check-deps.mjs", + "rpa-cli": "tsx scripts/rpa-cli.ts", "catalog": "node scripts/build-catalog.mjs", "snapshot": "vitest run scripts/capability-snapshot.test.ts", "package": "node scripts/package.mjs", @@ -61,6 +62,7 @@ "electron-builder": "^26.15.7", "electron-vite": "^6.0.0", "typescript": "^5.7.2", + "tsx": "^4.19.2", "vite": "^7.1.0", "vitest": "^2.1.8" }, diff --git a/scripts/rpa-cli.ts b/scripts/rpa-cli.ts new file mode 100644 index 0000000..f1b131a --- /dev/null +++ b/scripts/rpa-cli.ts @@ -0,0 +1,69 @@ +/** + * rpa-core CLI host(任务 5.1):Node 直接拉起 createEngine() + WindowsDriver, + * 不经过 Electron,验证包的零宿主可运行性。 + * + * 跑通 5 个代表能力(全部只读或落在临时目录,可重复执行): + * 1. 桌面(PowerShell user32):Window_GetActiveWindow —— 读前台窗口标题 + * 2. Excel(exceljs): Excel_Cs_NewV5 —— 临时目录新建工作簿 + * 3. HTTP(fetch): Http_Get —— GET 百度首页 + * 4. 文件(fs): File_Write / File_Read + * 5. 窗口/屏幕(PowerShell): Window_GetScreenSize + * + * 运行:npm run rpa-cli + */ +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { + createEngine, + capabilityCount, + getHandler, + registerAll, + type CapabilityHandler, + type RunContext +} from "@rpa/core"; +import "@rpa/core/capabilities"; + +const ctx = { + runId: "rpa-cli", + flowId: "rpa-cli", + flow: { id: "rpa-cli", name: "rpa-cli", nodes: [], edges: [] }, + vars: {}, + secrets: {}, + signal: new AbortController().signal, + evidenceDir: "", + log: (message: string) => console.log(" " + message), + componentOf: () => undefined +} as unknown as RunContext; +const node = (componentId: string) => ({ id: "rpa-cli", componentId, position: { x: 0, y: 0 }, values: {}, options: {} }); + +async function run(name: string, handler: CapabilityHandler, args: Record): Promise { + process.stdout.write(`[${name}] `); + const result = await handler(ctx, node(name), args, undefined as never); + console.log("OK ->", typeof result === "string" ? result.slice(0, 120) : JSON.stringify(result)?.slice(0, 200)); +} + +async function main(): Promise { + const engine = createEngine(); + await registerAll(engine); + console.log(`rpa-core CLI host:引擎已创建,注册能力 ${capabilityCount()} 个\n`); + + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "rpa-cli-")); + try { + await run("Window_GetActiveWindow", getHandler("Window_GetActiveWindow")!, {}); + await run("Window_GetScreenSize", getHandler("Window_GetScreenSize")!, {}); + await run("Excel_Cs_NewV5", getHandler("Excel_Cs_NewV5")!, { filePath: tmpDir, name: "rpa-cli-demo.xlsx" }); + const file = path.join(tmpDir, "hello.txt"); + await run("File_Write", getHandler("File_Write")!, { path: file, content: "hello from rpa-core CLI" }); + await run("File_Read", getHandler("File_Read")!, { path: file }); + await run("Http_Get", getHandler("Http_Get")!, { url: "https://www.baidu.com", timeout: 15 }); + console.log("\n5 项代表能力全部通过 ✓"); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } +} + +void main().catch((error) => { + console.error("\nCLI host 失败:", (error as Error).message); + process.exit(1); +}); diff --git a/tsconfig.json b/tsconfig.json index 3f434f6..86d02db 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,8 @@ "src/**/*.tsx", "packages/rpa-core/src/**/*.ts", "electron.vite.config.ts", - "scripts/**/*.mjs" + "scripts/**/*.mjs", + "scripts/rpa-cli.ts" ], "exclude": ["node_modules", "out", "release"] }