import test from "node:test"; import assert from "node:assert/strict"; import { spawn } from "node:child_process"; import fs from "node:fs/promises"; import http from "node:http"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); async function writeOpenMarkerScript(markerFile) { const scriptDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-open-marker-script-")); const scriptPath = path.join(scriptDir, "open-marker.mjs"); await fs.writeFile( scriptPath, `import fs from "node:fs";\nfs.writeFileSync(${JSON.stringify(markerFile)}, process.argv[2] || "", "utf8");\n`, "utf8", ); await fs.chmod(scriptPath, 0o755); return { scriptDir, scriptPath }; } async function writeArgumentMarkerCommand(markerFile, commandName = "open") { const scriptDir = await fs.mkdtemp(path.join(os.tmpdir(), `boss-${commandName}-marker-script-`)); const scriptPath = path.join(scriptDir, commandName); await fs.writeFile( scriptPath, [ "#!/usr/bin/env node", 'import fs from "node:fs";', `fs.writeFileSync(${JSON.stringify(markerFile)}, JSON.stringify(process.argv.slice(2)), "utf8");`, ].join("\n"), "utf8", ); await fs.chmod(scriptPath, 0o755); return { scriptDir, scriptPath }; } async function writeBrowserAutomationScript(logFile) { const scriptDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-automation-script-")); const scriptPath = path.join(scriptDir, "browser-automation.mjs"); await fs.writeFile( scriptPath, [ '#!/usr/bin/env node', 'import fs from "node:fs";', `fs.appendFileSync(${JSON.stringify(logFile)}, JSON.stringify(process.argv.slice(2)) + "\\n", "utf8");`, 'if (process.argv.includes("eval")) {', ' process.stdout.write("Boss Automated Title\\n");', '}', ].join("\n"), "utf8", ); await fs.chmod(scriptPath, 0o755); return { scriptDir, scriptPath }; } async function writeCodexHomePlaywrightWrapper(codexHome, logFile) { const wrapperDir = path.join(codexHome, "skills", "playwright", "scripts"); await fs.mkdir(wrapperDir, { recursive: true }); const wrapperPath = path.join(wrapperDir, "playwright_cli.sh"); await fs.writeFile( wrapperPath, [ "#!/bin/zsh", `printf '%s\\n' \"$(python3 -c 'import json,sys; args=sys.argv[1:]; print(json.dumps(args[1:] if args[:1] == [\"--\"] else args))' -- \"$@\")\" >> ${JSON.stringify(logFile)}`, 'if [[ " $* " == *" eval "* ]]; then', ' printf "Boss Auto Wrapper Title\\n"', "fi", ].join("\n"), "utf8", ); await fs.chmod(wrapperPath, 0o755); return wrapperPath; } async function runRuntimeWithServer(scriptPath, payload, options = {}) { return new Promise((resolve, reject) => { const child = spawn(process.execPath, [scriptPath], { cwd: repoRoot, env: { ...process.env, ...(options.env || {}), }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write(JSON.stringify(payload)); child.stdin.end(); }); } async function runRuntime(scriptPath, payload, options = {}) { return new Promise((resolve, reject) => { const child = spawn(process.execPath, [scriptPath], { cwd: repoRoot, env: { ...process.env, BOSS_BROWSER_AUTOMATION_MODE: "off", ...(options.env || {}), }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write(JSON.stringify(payload)); child.stdin.end(); }); } test("browser smoke runtime returns normalized completed payload", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-smoke-1", objective: "打开 boss 控制台首页", context: { riskLevel: "medium", }, }); assert.equal(result.status, "completed"); assert.equal(result.requestId, "browser-smoke-1"); assert.match(result.replyBody, /浏览器控制已完成/); assert.match(result.replyBody, /打开 boss 控制台首页/); }); test("browser smoke runtime emits target url when objective contains a website", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-smoke-url", objective: "打开 https://example.com 看一下首页", context: { riskLevel: "medium", dryRun: true, }, }); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); assert.match(result.executionSummary, /open_url/); }); test("browser smoke runtime normalizes bare domains from app control text", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-smoke-bare-domain", objective: "打开Chrome浏览器,访问 example.com,完成后回复一句任务小结。", context: { riskLevel: "medium", dryRun: true, }, }); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); assert.match(result.executionSummary, /open_url/); }); test("browser smoke runtime derives a YouTube search url from natural language playback requests", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-youtube-search", objective: "打开浏览器,用浏览器打开YouTube,找一个蔡徐坤的MV播放", context: { riskLevel: "medium", dryRun: true, }, }); assert.equal(result.status, "completed"); assert.equal( result.targetUrl, "https://www.youtube.com/results?search_query=%E8%94%A1%E5%BE%90%E5%9D%A4%20MV", ); assert.match(result.executionSummary, /open_url/); }); test("browser smoke runtime can invoke configured browser automation command", async () => { const markerDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-automation-marker-")); const markerFile = path.join(markerDir, "automation.log"); let automationScript; try { automationScript = await writeBrowserAutomationScript(markerFile); const result = await runRuntime( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-automation-1", objective: "打开 https://example.com 看一下首页", context: { riskLevel: "medium", dryRun: false, }, }, { env: { BOSS_BROWSER_AUTOMATION_MODE: "playwright", BOSS_BROWSER_AUTOMATION_COMMAND: process.execPath, BOSS_BROWSER_AUTOMATION_ARGS_JSON: JSON.stringify([automationScript.scriptPath]), BOSS_BROWSER_AUTOMATION_SESSION: "boss-browser-test", BOSS_BROWSER_VISIBLE_OPEN_AFTER_AUTOMATION: "off", }, }, ); assert.equal(result.status, "completed"); assert.match(result.replyBody, /Boss Automated Title/); const lines = (await fs.readFile(markerFile, "utf8")).trim().split(/\r?\n/).map((line) => JSON.parse(line)); assert.deepEqual(lines[0], ["--session", "boss-browser-test", "open", "https://example.com"]); assert.deepEqual(lines[1], ["--session", "boss-browser-test", "eval", "document.title"]); } finally { if (automationScript?.scriptDir) { await fs.rm(automationScript.scriptDir, { recursive: true, force: true }); } await fs.rm(markerDir, { recursive: true, force: true }); } }); test("browser smoke runtime still opens a visible browser after automation succeeds", async () => { const markerDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-visible-after-automation-")); const automationLog = path.join(markerDir, "automation.log"); const openerMarker = path.join(markerDir, "visible-open.txt"); let automationScript; let openerScript; try { automationScript = await writeBrowserAutomationScript(automationLog); openerScript = await writeOpenMarkerScript(openerMarker); const result = await runRuntimeWithServer( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-visible-after-automation", objective: "打开 https://example.com 看一下首页", context: { riskLevel: "medium", dryRun: false, }, }, { env: { BOSS_BROWSER_AUTOMATION_MODE: "playwright", BOSS_BROWSER_AUTOMATION_COMMAND: process.execPath, BOSS_BROWSER_AUTOMATION_ARGS_JSON: JSON.stringify([automationScript.scriptPath]), BOSS_BROWSER_OPEN_COMMAND: process.execPath, BOSS_BROWSER_OPEN_ARGS_JSON: JSON.stringify([openerScript.scriptPath]), }, }, ); assert.equal(result.status, "completed"); assert.match(result.replyBody, /Boss Automated Title/); assert.match(result.executionSummary, /browser_automation_executed\+open_url_executed/); assert.equal(await fs.readFile(openerMarker, "utf8"), "https://example.com"); } finally { if (automationScript?.scriptDir) { await fs.rm(automationScript.scriptDir, { recursive: true, force: true }); } if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(markerDir, { recursive: true, force: true }); } }); test("browser smoke runtime falls back to opener when browser automation fails", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-automation-fallback-")); const openerMarker = path.join(marker, "opened.txt"); let openerScript; try { const failingAutomationPath = path.join(marker, "failing-automation.mjs"); await fs.writeFile(failingAutomationPath, "process.stderr.write('automation failed'); process.exit(1);", "utf8"); openerScript = await writeOpenMarkerScript(openerMarker); const result = await runRuntime( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-automation-fallback", objective: "打开 example.com 看一下首页", context: { riskLevel: "medium", dryRun: false, }, }, { env: { BOSS_BROWSER_AUTOMATION_MODE: "playwright", BOSS_BROWSER_AUTOMATION_COMMAND: process.execPath, BOSS_BROWSER_AUTOMATION_ARGS_JSON: JSON.stringify([failingAutomationPath]), BOSS_BROWSER_OPEN_COMMAND: process.execPath, BOSS_BROWSER_OPEN_ARGS_JSON: JSON.stringify([openerScript.scriptPath]), }, }, ); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); assert.match(result.executionSummary, /open_url_executed/); assert.equal(await fs.readFile(openerMarker, "utf8"), "https://example.com"); } finally { if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("browser smoke runtime auto-detects bundled playwright wrapper and uses request id as session", async () => { const tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-autodetect-")); const logFile = path.join(tmpRoot, "wrapper.log"); try { const codexHome = path.join(tmpRoot, ".codex"); await writeCodexHomePlaywrightWrapper(codexHome, logFile); const result = await runRuntimeWithServer( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-auto-session", objective: "打开 https://example.com 看一下首页", context: { riskLevel: "medium", dryRun: false, }, }, { env: { CODEX_HOME: codexHome, BOSS_BROWSER_VISIBLE_OPEN_AFTER_AUTOMATION: "off", }, }, ); assert.equal(result.status, "completed"); assert.match(result.replyBody, /Boss Auto Wrapper Title/); const lines = (await fs.readFile(logFile, "utf8")).trim().split(/\r?\n/).map((line) => JSON.parse(line)); assert.deepEqual(lines[0], ["--session", "browser-auto-session", "open", "https://example.com"]); assert.deepEqual(lines[1], ["--session", "browser-auto-session", "eval", "document.title"]); } finally { await fs.rm(tmpRoot, { recursive: true, force: true }); } }); test("browser smoke runtime fetches page title for a reachable target url", async () => { const server = http.createServer((_request, response) => { response.writeHead(200, { "content-type": "text/html; charset=utf-8" }); response.end("Boss Browser Runtime Testok"); }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const address = server.address(); const port = typeof address === "object" && address ? address.port : 0; try { const result = await runRuntimeWithServer(path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-smoke-title", objective: `打开 http://127.0.0.1:${port}/ 看一下首页`, context: { riskLevel: "medium", dryRun: false, }, }, { env: { BOSS_BROWSER_AUTOMATION_MODE: "fetch", }, }); assert.equal(result.status, "completed"); assert.match(result.replyBody, /Boss Browser Runtime Test/); assert.match(result.executionSummary, /title=Boss Browser Runtime Test/); } finally { await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))); } }); test("computer use smoke runtime returns normalized completed payload", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "computer-use-smoke.mjs"), { requestKind: "desktop_control", requestId: "computer-smoke-1", objective: "打开系统设置", context: { riskLevel: "high", dryRun: true, }, }); assert.equal(result.status, "completed"); assert.equal(result.requestId, "computer-smoke-1"); assert.match(result.replyBody, /桌面控制已完成/); assert.match(result.replyBody, /打开系统设置/); }); test("computer use smoke runtime emits target app when objective contains an app name", async () => { const result = await runRuntime(path.join(repoRoot, "scripts", "computer-use-smoke.mjs"), { requestKind: "desktop_control", requestId: "computer-smoke-app", objective: "打开微信并准备切到聊天窗口", context: { riskLevel: "medium", dryRun: true, }, }); assert.equal(result.status, "completed"); assert.equal(result.targetApp, "微信"); assert.match(result.executionSummary, /open_wechat|open_app/); }); test("computer use smoke runtime auto-handles safe cross-platform dialog snapshots", async () => { const result = await runRuntime( path.join(repoRoot, "scripts", "computer-use-smoke.mjs"), { requestKind: "desktop_control", requestId: "computer-dialog-safe", objective: "打开 QQ", context: { riskLevel: "medium", dryRun: true, }, }, { env: { BOSS_DIALOG_GUARD_ENABLED: "true", BOSS_DIALOG_GUARD_SNAPSHOT_JSON: JSON.stringify({ platform: "win32", deviceId: "win-node", appName: "QQ", title: "Welcome", text: "Welcome. Not now", buttons: ["Get started", "Not now"], }), }, }, ); assert.equal(result.status, "completed"); assert.equal(result.dialogGuard?.disposition, "auto_action"); assert.equal(result.dialogGuard?.button, "Not now"); assert.match(result.executionSummary, /dialogGuard=auto_action/); }); test("computer use smoke runtime invokes configured platform dialog action command for safe dialogs", async () => { const markerDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-dialog-action-marker-")); const markerFile = path.join(markerDir, "action.json"); let actionCommand; try { actionCommand = await writeArgumentMarkerCommand(markerFile, "dialog-action"); const result = await runRuntime( path.join(repoRoot, "scripts", "computer-use-smoke.mjs"), { requestKind: "desktop_control", requestId: "computer-dialog-action", objective: "打开 QQ", context: { riskLevel: "medium", dryRun: true, }, }, { env: { BOSS_DIALOG_GUARD_ENABLED: "true", BOSS_WINDOWS_DIALOG_GUARD_ACTION_COMMAND: actionCommand.scriptPath, BOSS_DIALOG_GUARD_SNAPSHOT_JSON: JSON.stringify({ platform: "win32", deviceId: "win-node", appName: "QQ", title: "Welcome", text: "Welcome. Not now", buttons: ["Get started", "Not now"], }), }, }, ); assert.equal(result.status, "completed"); assert.equal(result.dialogGuard?.actionApplied, true); const args = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.ok(args.includes("--platform")); assert.ok(args.includes("win32")); assert.ok(args.includes("--button")); assert.ok(args.includes("Not now")); } finally { if (actionCommand?.scriptDir) { await fs.rm(actionCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(markerDir, { recursive: true, force: true }); } }); test("computer use smoke runtime pauses before action for blocked system permission dialogs", async () => { const result = await runRuntime( path.join(repoRoot, "scripts", "computer-use-smoke.mjs"), { requestKind: "desktop_control", requestId: "computer-dialog-blocked", objective: "打开系统设置", context: { riskLevel: "high", dryRun: false, }, }, { env: { BOSS_DIALOG_GUARD_ENABLED: "true", BOSS_DIALOG_GUARD_SNAPSHOT_JSON: JSON.stringify({ platform: "darwin", deviceId: "mac-node", appName: "System Settings", title: "Screen Recording", text: "BossComputerUseHelper would like to record this computer's screen", buttons: ["Allow", "Don't Allow"], }), }, }, ); assert.equal(result.status, "needs_user_action"); assert.equal(result.kind, "dialog_intervention_required"); assert.equal(result.risk, "high"); assert.deepEqual(result.availableActions, ["handled_on_device", "cancel_task"]); }); test("browser smoke runtime writes action artifact when BOSS_CONTROL_ARTIFACT_DIR is set", async () => { const artifactDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-artifacts-")); try { const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "browser-control-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_CONTROL_ARTIFACT_DIR: artifactDir, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "browser_control", requestId: "browser-artifact-1", objective: "打开 https://example.com 看一下首页", context: { dryRun: true }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.ok(Array.isArray(result.artifacts)); assert.ok(result.artifacts[0]?.path); const artifactText = await fs.readFile(result.artifacts[0].path, "utf8"); assert.match(artifactText, /https:\/\/example\.com/); } finally { await fs.rm(artifactDir, { recursive: true, force: true }); } }); test("browser smoke runtime can execute an injected url opener when not dry-run", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-open-")); let openerScript; const markerFile = path.join(marker, "opened.txt"); try { openerScript = await writeOpenMarkerScript(markerFile); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "browser-control-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_BROWSER_AUTOMATION_MODE: "off", BOSS_BROWSER_OPEN_COMMAND: process.execPath, BOSS_BROWSER_OPEN_ARGS_JSON: JSON.stringify([openerScript.scriptPath]), }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "browser_control", requestId: "browser-open-1", objective: "打开 https://example.com 看一下首页", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); assert.match(result.executionSummary, /executed/); const openedUrl = await fs.readFile(markerFile, "utf8"); assert.equal(openedUrl, "https://example.com"); } finally { if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("browser smoke runtime opens Chrome when app control text asks for Chrome", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-chrome-open-")); const markerFile = path.join(marker, "open-args.json"); let openerCommand; try { openerCommand = await writeArgumentMarkerCommand(markerFile, "open"); const result = await runRuntime( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-open-chrome", objective: "打开Chrome浏览器,访问 example.com,完成后回复一句任务小结。", context: { dryRun: false }, }, { env: { BOSS_BROWSER_OPEN_COMMAND: openerCommand.scriptPath, }, }, ); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); assert.deepEqual(JSON.parse(await fs.readFile(markerFile, "utf8")), [ "-a", "Google Chrome", "https://example.com", ]); } finally { if (openerCommand?.scriptDir) { await fs.rm(openerCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("browser smoke runtime uses osascript for real Chrome URL opens on macOS", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-browser-chrome-osascript-")); const osascriptMarker = path.join(marker, "osascript-args.json"); let osascriptCommand; try { osascriptCommand = await writeArgumentMarkerCommand(osascriptMarker, "osascript"); const failingOpenPath = path.join(osascriptCommand.scriptDir, "open"); await fs.writeFile( failingOpenPath, "#!/usr/bin/env node\nprocess.stderr.write('open should not be used for Chrome URL opens'); process.exit(1);\n", "utf8", ); await fs.chmod(failingOpenPath, 0o755); const result = await runRuntime( path.join(repoRoot, "scripts", "browser-control-smoke.mjs"), { requestKind: "browser_control", requestId: "browser-open-chrome-osascript", objective: "打开Chrome浏览器,访问 example.com,完成后回复一句任务小结。", context: { dryRun: false }, }, { env: { PATH: `${osascriptCommand.scriptDir}:${process.env.PATH}`, }, }, ); assert.equal(result.status, "completed"); assert.equal(result.targetUrl, "https://example.com"); const args = JSON.parse(await fs.readFile(osascriptMarker, "utf8")); assert.match(args.join(" "), /Google Chrome/); assert.match(args.join(" "), /https:\/\/example\.com/); } finally { if (osascriptCommand?.scriptDir) { await fs.rm(osascriptCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime can execute an injected app opener when not dry-run", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-open-")); let openerScript; const markerFile = path.join(marker, "opened.txt"); try { openerScript = await writeOpenMarkerScript(markerFile); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "open", BOSS_COMPUTER_USE_OPEN_APP_COMMAND: process.execPath, BOSS_COMPUTER_USE_OPEN_APP_ARGS_JSON: JSON.stringify([openerScript.scriptPath]), }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-open-1", objective: "打开微信并准备切到聊天窗口", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.equal(result.targetApp, "微信"); assert.match(result.executionSummary, /executed/); const openedApp = await fs.readFile(markerFile, "utf8"); assert.equal(openedApp, "微信"); } finally { if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime defaults to open -a style args for macOS opener", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-open-default-")); let openerCommand; const markerFile = path.join(marker, "argv.json"); try { openerCommand = await writeArgumentMarkerCommand(markerFile, "open"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "open", BOSS_COMPUTER_USE_OPEN_APP_COMMAND: openerCommand.scriptPath, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-open-default", objective: "打开微信并准备切到聊天窗口", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.deepEqual(argv, ["-a", "微信"]); } finally { if (openerCommand?.scriptDir) { await fs.rm(openerCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime maps Chrome to Google Chrome for macOS app opens", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-open-chrome-")); let openerCommand; const markerFile = path.join(marker, "argv.json"); try { openerCommand = await writeArgumentMarkerCommand(markerFile, "open"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "open", BOSS_COMPUTER_USE_OPEN_APP_COMMAND: openerCommand.scriptPath, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-open-chrome", objective: "打开Chrome浏览器", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.equal(result.targetApp, "Chrome"); assert.equal(result.automationTargetApp, "Google Chrome"); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.deepEqual(argv, ["-a", "Google Chrome"]); } finally { if (openerCommand?.scriptDir) { await fs.rm(openerCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime opens browser urls directly without keystroke automation", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-open-browser-url-")); let openerCommand; const markerFile = path.join(marker, "argv.json"); try { openerCommand = await writeArgumentMarkerCommand(markerFile, "open"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "osascript", BOSS_COMPUTER_USE_OPEN_APP_COMMAND: openerCommand.scriptPath, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-open-browser-url", objective: "打开软件 Chrome,输入“https://example.com”,回车", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.equal(result.targetApp, "Chrome"); assert.equal(result.automationTargetApp, "Google Chrome"); assert.equal(result.targetUrl, "https://example.com"); assert.match(result.executionSummary, /open_app_url_executed/); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.deepEqual(argv, ["-a", "Google Chrome", "https://example.com"]); } finally { if (openerCommand?.scriptDir) { await fs.rm(openerCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime can prepend configured open -a style args", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-open-default-")); let openerCommand; const markerFile = path.join(marker, "argv.json"); try { openerCommand = await writeArgumentMarkerCommand(markerFile, "open"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "open", BOSS_COMPUTER_USE_OPEN_APP_COMMAND: openerCommand.scriptPath, BOSS_COMPUTER_USE_OPEN_APP_ARGS_JSON: JSON.stringify(["-a"]), }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-open-default", objective: "打开微信并准备切到聊天窗口", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.deepEqual(argv, ["-a", "微信"]); } finally { if (openerCommand?.scriptDir) { await fs.rm(openerCommand.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime supports osascript mode via injected command", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-osascript-")); let openerScript; const markerFile = path.join(marker, "argv.json"); try { openerScript = await writeArgumentMarkerCommand(markerFile, "osascript"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "osascript", PATH: `${openerScript.scriptDir}:${process.env.PATH || ""}`, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-osascript", objective: "打开微信并准备切到聊天窗口", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.match(result.executionSummary, /mode=osascript/); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.equal(argv[0], "-e"); assert.match(argv[1], /tell application "微信"/); } finally { if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime types quoted text in osascript mode and can submit", async () => { const marker = await fs.mkdtemp(path.join(os.tmpdir(), "boss-computer-osascript-type-")); let openerScript; const markerFile = path.join(marker, "argv.json"); try { openerScript = await writeArgumentMarkerCommand(markerFile, "osascript"); const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_COMPUTER_USE_MODE: "osascript", PATH: `${openerScript.scriptDir}:${process.env.PATH || ""}`, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "computer-osascript-type", objective: "打开微信并输入“Boss 已接管当前线程”后发送", context: { dryRun: false }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.equal(result.typedText, "Boss 已接管当前线程"); const argv = JSON.parse(await fs.readFile(markerFile, "utf8")); assert.equal(argv[0], "-e"); assert.match(argv[1], /keystroke "Boss 已接管当前线程"/); assert.match(argv[1], /key code 36/); } finally { if (openerScript?.scriptDir) { await fs.rm(openerScript.scriptDir, { recursive: true, force: true }); } await fs.rm(marker, { recursive: true, force: true }); } }); test("computer use smoke runtime writes action artifact when BOSS_CONTROL_ARTIFACT_DIR is set", async () => { const artifactDir = await fs.mkdtemp(path.join(os.tmpdir(), "boss-desktop-artifacts-")); try { const result = await new Promise((resolve, reject) => { const child = spawn(process.execPath, [path.join(repoRoot, "scripts", "computer-use-smoke.mjs")], { cwd: repoRoot, env: { ...process.env, BOSS_CONTROL_ARTIFACT_DIR: artifactDir, }, stdio: ["pipe", "pipe", "pipe"], }); let stdout = ""; let stderr = ""; child.stdout.setEncoding("utf8"); child.stderr.setEncoding("utf8"); child.stdout.on("data", (chunk) => { stdout += chunk; }); child.stderr.on("data", (chunk) => { stderr += chunk; }); child.on("error", reject); child.on("close", (code) => { if (code !== 0) { reject(new Error(stderr.trim() || `exit code ${code}`)); return; } try { resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1) || "")); } catch (error) { reject(error); } }); child.stdin.write( JSON.stringify({ requestKind: "desktop_control", requestId: "desktop-artifact-1", objective: "打开系统设置", context: { dryRun: true }, }), ); child.stdin.end(); }); assert.equal(result.status, "completed"); assert.ok(Array.isArray(result.artifacts)); assert.ok(result.artifacts[0]?.path); const artifactText = await fs.readFile(result.artifacts[0].path, "utf8"); assert.match(artifactText, /系统设置/); assert.match(artifactText, /mode/); } finally { await fs.rm(artifactDir, { recursive: true, force: true }); } });