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 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",
},
},
);
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 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,
},
},
);
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("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 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 });
}
});