import { spawn } from "node:child_process";
import { rm, stat } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
const PERMISSION_DEFS = [
{
key: "accessibility",
label: "辅助功能",
description: "用于点击、输入和读取可访问控件",
tier: "core",
},
{
key: "screenRecording",
label: "屏幕录制",
description: "用于识别桌面画面和系统弹窗",
tier: "core",
},
];
const MACOS_PERMISSION_SETTINGS = {
core: "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_Accessibility",
accessibility: "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_Accessibility",
screenRecording: "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_ScreenCapture",
};
const AUTO_PREFLIGHT_PERMISSION_KEYS = new Set(["accessibility", "screenRecording"]);
const NATIVE_PERMISSION_QUERY_PARAMS = {
accessibility: "nativeAccessibility",
screenRecording: "nativeScreenRecording",
};
const BOSS_AGENT_BUNDLE_ID = "com.hyzq.boss.agent";
const BOSS_COMPUTER_USE_HELPER_BUNDLE_ID = "site.hyzq.boss.computer-use-helper";
const BOSS_COMPUTER_USE_HELPER_APP_CANDIDATES = [
path.join(os.homedir(), "Applications/BossComputerUseHelper.app"),
"/Applications/BossComputerUseHelper.app",
];
const HELPER_SCREEN_RECORDING_CACHE_TTL_MS = 30_000;
let helperScreenRecordingCache = {
status: "unknown",
expiresAt: 0,
};
const BOSS_AGENT_DEFAULTS_DOMAIN = "com.hyzq.boss.agent";
const TCC_PERMISSION_SERVICES = {
kTCCServiceAccessibility: "accessibility",
kTCCServiceScreenCapture: "screenRecording",
};
const TCC_PERMISSION_CLIENTS = {
kTCCServiceAccessibility: [BOSS_AGENT_BUNDLE_ID],
kTCCServiceScreenCapture: [BOSS_AGENT_BUNDLE_ID, BOSS_COMPUTER_USE_HELPER_BUNDLE_ID],
};
const TCC_PERMISSION_DATABASES = [
"/Library/Application Support/com.apple.TCC/TCC.db",
path.join(os.homedir(), "Library/Application Support/com.apple.TCC/TCC.db"),
];
function nonEmpty(value) {
const text = String(value ?? "").trim();
return text || undefined;
}
function escapeHtml(value) {
return String(value ?? "")
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}
function maskValue(value) {
const text = nonEmpty(value);
if (!text) return "";
if (text.length <= 8) return "••••";
return `${text.slice(0, 4)}••••${text.slice(-4)}`;
}
function sqlQuote(value) {
return `'${String(value ?? "").replaceAll("'", "''")}'`;
}
function normalizePermissionStatus(value) {
return value === "granted" || value === "missing" || value === "unknown" ? value : "unknown";
}
function isPermissionStatus(value) {
return value === "granted" || value === "missing" || value === "unknown";
}
function statusTone(status) {
if (status === "granted" || status === "valid" || status === "connected" || status === "bound") {
return "good";
}
if (status === "missing" || status === "expired" || status === "disconnected") {
return "bad";
}
return "warn";
}
function formatDate(value) {
const text = nonEmpty(value);
if (!text) return "绑定后显示";
const date = new Date(text);
if (Number.isNaN(date.getTime())) return text;
return new Intl.DateTimeFormat("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(date);
}
function buildBindingPayload(config) {
const controlPlaneUrl = nonEmpty(config.controlPlaneUrl) ?? "https://boss.hyzq.net";
const params = new URLSearchParams({
server: controlPlaneUrl,
deviceId: nonEmpty(config.deviceId) ?? "local-device",
name: nonEmpty(config.name) ?? "本机电脑",
});
const pairingCode = nonEmpty(config.pairingCode);
if (pairingCode) params.set("pairingCode", pairingCode);
return `boss://agent-bind?${params.toString()}`;
}
function resolveApiUsage(config) {
return {
primary:
nonEmpty(config.primaryApiLabel) ??
nonEmpty(config.apiUsage?.primary) ??
nonEmpty(config.masterAgentModel) ??
"由 Boss 后台统一配置",
backup:
nonEmpty(config.backupApiLabel) ??
nonEmpty(config.apiUsage?.backup) ??
"未启用",
status:
nonEmpty(config.apiUsage?.status) ??
(config.masterAgentEnabled === false ? "未启用主 Agent" : "可用"),
};
}
function resolveLicense(config, bound) {
const license = config.license && typeof config.license === "object" ? config.license : {};
if (!bound) {
return {
status: "pending_binding",
label: "未授权 · 绑定后校验",
enterpriseName: "绑定后显示",
expiresAt: nonEmpty(config.licenseExpiresAt) ?? "",
expiresAtLabel: "绑定后显示",
scope: "桌面控制 / 浏览器控制 / Skill 同步",
};
}
const status = nonEmpty(license.status) ?? "valid";
const expiresAt = nonEmpty(license.expiresAt) ?? nonEmpty(config.licenseExpiresAt) ?? "";
return {
status,
label: status === "valid" ? "正版授权正常" : status === "expired" ? "授权已过期" : "授权状态待确认",
enterpriseName: nonEmpty(license.enterpriseName) ?? nonEmpty(config.enterpriseName) ?? "默认公司",
expiresAt,
expiresAtLabel: formatDate(expiresAt),
scope: nonEmpty(license.scope) ?? "桌面控制 / 浏览器控制 / Skill 同步",
};
}
function normalizeCommandArgs(value, fallback = []) {
if (!Array.isArray(value)) return [...fallback];
return value.map((item) => nonEmpty(item)).filter(Boolean);
}
function resolveBooleanWithDefault(value, defaultValue = false) {
if (value === undefined || value === null || value === "") return defaultValue;
if (value === false || value === "false" || value === "0" || value === 0) return false;
return true;
}
function resolveCodexRemoteControl(config, appServerEnabled) {
const enabled = resolveBooleanWithDefault(config.codexRemoteControlEnabled, appServerEnabled);
const command = nonEmpty(config.codexRemoteControlCommand) ?? nonEmpty(config.codexAppServerCommand) ?? "codex";
const args = normalizeCommandArgs(config.codexRemoteControlArgs, ["remote-control", "start", "--json"]);
const startCommandLabel = [command, ...args].join(" ");
return {
enabled,
mode: enabled ? "managed_daemon" : "disabled",
command,
args,
startCommandLabel,
statusLabel: enabled ? "可托管启动" : "未启用",
summary: enabled
? "Codex Remote Control 会通过 App Server daemon 提供官方远控入口;当前状态页只展示能力,不在刷新时自动启动。"
: "Codex Remote Control daemon 未启用;远程控制会继续使用当前 App Server / Computer Use 配置。",
};
}
function resolveCodexBinding(config) {
const appServerEnabled = config.codexAppServerEnabled === true;
const codexComputerUseEnabled = config.codexComputerUseEnabled === true;
const command = nonEmpty(config.codexAppServerCommand) ?? "codex";
const defaultDesktopProvider = codexComputerUseEnabled
? "codex-computer-use"
: "cua-driver-computer-use";
const bindingStatus = appServerEnabled || codexComputerUseEnabled ? "connected" : "not_configured";
return {
bindingStatus,
statusLabel: bindingStatus === "connected" ? "已默认绑定" : "未默认绑定",
command,
appServerEnabled,
computerUseEnabled: codexComputerUseEnabled,
defaultDesktopProvider,
desktopProviderLabel:
defaultDesktopProvider === "codex-computer-use"
? "Codex Computer Use"
: "Boss CUA Driver",
fallbackProvider: "cua-driver-computer-use",
fallbackLabel: "Boss CUA Driver",
remoteControl: resolveCodexRemoteControl(config, appServerEnabled),
summary:
defaultDesktopProvider === "codex-computer-use"
? "远程控制默认走 Codex Computer Use,失败后回退 Boss CUA Driver。"
: "远程控制默认走 Boss CUA Driver。",
};
}
function resolveAgentOta(config, runtime) {
const enabledValue = config.bossAgentOtaEnabled;
const enabled = enabledValue === undefined ? true : enabledValue !== false && enabledValue !== "false";
const currentVersion = nonEmpty(config.bossAgentVersion) ?? "dev";
const lastStatus = runtime.lastBossAgentOtaStatus && typeof runtime.lastBossAgentOtaStatus === "object"
? runtime.lastBossAgentOtaStatus
: {};
const lastApply = runtime.lastBossAgentOtaApply && typeof runtime.lastBossAgentOtaApply === "object"
? runtime.lastBossAgentOtaApply
: {};
const latest = lastStatus.latest && typeof lastStatus.latest === "object" ? lastStatus.latest : null;
const hasUpdate = enabled && lastStatus.hasUpdate === true && Boolean(latest);
const latestVersion = nonEmpty(latest?.version) ?? "";
const applyStatus = nonEmpty(lastApply.status) ?? "";
return {
enabled,
currentVersion,
hasUpdate,
latestVersion,
latestFileName: nonEmpty(latest?.fileName) ?? "",
latestUpdatedAt: nonEmpty(latest?.updatedAt) ?? "",
lastCheckedAt: nonEmpty(lastStatus.checkedAt) ?? "",
lastApplyStatus: applyStatus,
lastApplyAt: nonEmpty(lastApply.completedAt) ?? "",
statusLabel: !enabled
? "未启用"
: hasUpdate
? "发现新版本"
: lastStatus.error
? "检查失败"
: "当前版本",
detail: !enabled
? "boss-agent OTA 已关闭"
: hasUpdate
? `最新:${latestVersion || "未知版本"}`
: lastStatus.error
? String(lastStatus.error)
: `当前:${currentVersion}`,
};
}
function permissionItems(defs, permissions) {
return defs.map((item) => ({
...item,
status: normalizePermissionStatus(permissions[item.key]),
}));
}
function resolvePermissionReadiness(coreItems, extendedItems) {
const coreGrantedCount = coreItems.filter((item) => item.status === "granted").length;
const extendedGrantedCount = extendedItems.filter((item) => item.status === "granted").length;
const coreReady = coreGrantedCount === coreItems.length;
const fullControlReady = coreReady && extendedGrantedCount === extendedItems.length;
const summary = coreReady ? "基础桌面控制已可用" : "基础桌面控制待授权,桌面接管不可用";
return {
coreReady,
fullControlReady,
coreGrantedCount,
coreTotal: coreItems.length,
extendedGrantedCount,
extendedTotal: extendedItems.length,
summary,
detail:
"参考 Codex Computer Use 的最小权限模型,boss-agent 只要求辅助功能和屏幕录制:辅助功能负责点击输入,屏幕录制可由 Boss Computer Use Helper 提供画面识别。",
};
}
function buildPermissionSetupPlan(coreItems, readiness) {
const actions = coreItems.map((item) => ({
key: item.key,
label: item.label,
description: item.description,
tier: item.tier,
status: item.status,
requiredForSilentControl: item.tier === "core",
canPreflight: AUTO_PREFLIGHT_PERMISSION_KEYS.has(item.key),
settingsUrl: MACOS_PERMISSION_SETTINGS[item.key] ?? MACOS_PERMISSION_SETTINGS.core,
openUrl: `/api/v1/boss-agent/permissions/open?target=${encodeURIComponent(item.key)}&returnTab=permissions`,
owner: "boss-agent.app",
}));
const missingRequiredActions = actions.filter(
(action) => action.requiredForSilentControl && action.status !== "granted",
);
return {
mode: "minimal_computer_use",
title: "基础桌面控制授权",
goal: "按 Codex Computer Use 的思路,只申请辅助功能和屏幕录制两项最小权限。",
silentUseReady: missingRequiredActions.length === 0,
primaryAction: {
label: "打开基础授权",
href: "/api/v1/boss-agent/permissions/open?target=core&returnTab=permissions",
settingsUrl: MACOS_PERMISSION_SETTINGS.core,
},
actions,
missingKeys: missingRequiredActions.map((action) => action.key),
missingRequiredKeys: missingRequiredActions.map((action) => action.key),
optionalMissingKeys: [],
summary: readiness.coreReady
? "基础桌面控制已可用;后续控制只校验这两项权限。"
: "仍缺少基础桌面控制权限,请先授权辅助功能和屏幕录制。",
persistenceNote:
"macOS 会把授权持久写入系统隐私数据库;稳定签名后,后续更新不会因为二进制哈希变化反复丢失授权。",
};
}
export function mergeBossAgentNativePermissionOverrides(permissions = {}, queryParams = {}) {
const getQueryValue = (name) => {
if (typeof queryParams.get === "function") return queryParams.get(name);
return queryParams[name];
};
const merged = {};
for (const permissionKey of Object.keys(NATIVE_PERMISSION_QUERY_PARAMS)) {
if (isPermissionStatus(permissions[permissionKey])) {
merged[permissionKey] = permissions[permissionKey];
}
}
for (const [permissionKey, queryKey] of Object.entries(NATIVE_PERMISSION_QUERY_PARAMS)) {
const value = getQueryValue(queryKey);
if (isPermissionStatus(value)) {
if (merged[permissionKey] === "granted" && value !== "granted") {
continue;
}
merged[permissionKey] = value;
}
}
return merged;
}
export function mergeBossAgentStoredNativePermissions(permissions = {}, storedPermissions = {}) {
const merged = { ...permissions };
for (const permissionKey of Object.keys(NATIVE_PERMISSION_QUERY_PARAMS)) {
if (storedPermissions[permissionKey] === "granted") {
merged[permissionKey] = "granted";
}
}
return merged;
}
export function mergeBossComputerUseHelperScreenRecordingPermission(permissions = {}, helperStatus = "unknown") {
if (helperStatus !== "granted") return { ...permissions };
return {
...permissions,
screenRecording: "granted",
};
}
export function mergeBossAgentAppTccPermissions(permissions = {}, tccRows = "") {
const merged = { ...permissions };
const granted = new Set();
for (const rawLine of String(tccRows ?? "").split(/\r?\n/)) {
const line = rawLine.trim();
if (!line) continue;
const parts = line.split("|");
const [service] = parts;
const authValue = parts.length >= 3 ? parts[2] : parts[1];
const client = parts.length >= 3 ? parts[1] : BOSS_AGENT_BUNDLE_ID;
const permissionKey = TCC_PERMISSION_SERVICES[service];
if (!permissionKey) continue;
const allowedClients = TCC_PERMISSION_CLIENTS[service] ?? [];
if (client && allowedClients.length > 0 && !allowedClients.includes(client)) continue;
if (authValue === "2") {
merged[permissionKey] = "granted";
granted.add(permissionKey);
} else if (!granted.has(permissionKey) && authValue === "0") {
merged[permissionKey] = "missing";
}
}
return merged;
}
function resolveSkills(runtime) {
const rawSkills = Array.isArray(runtime.lastSkills) ? runtime.lastSkills : [];
const items = rawSkills
.map((item) => ({
name: nonEmpty(item?.name),
category: nonEmpty(item?.category) ?? "本机",
path: nonEmpty(item?.path) ?? "",
description: nonEmpty(item?.description) ?? "",
status: nonEmpty(item?.status) ?? "deployed",
}))
.filter((item) => item.name);
const syncOk = runtime.lastSkillSyncOk === true;
return {
total: items.length,
items: items.slice(0, 8),
syncOk,
syncStatus: syncOk ? "已同步" : items.length > 0 ? "待确认" : "未同步",
syncAt: nonEmpty(runtime.lastSkillSyncAt) ?? "",
summary: items.length > 0 ? `已部署 ${items.length} 个 Skill` : "本机暂无已同步 Skill",
};
}
export function buildBossAgentStatus(config = {}, runtime = {}, options = {}) {
const now = nonEmpty(options.now) ?? new Date().toISOString();
const token = nonEmpty(runtime.issuedToken) ?? nonEmpty(config.token);
const account = nonEmpty(config.account);
const bound = Boolean(token && account);
const permissions = options.permissions ?? {};
const serverOk = runtime.lastHeartbeatOk === true;
const qrPayload = bound ? "" : buildBindingPayload(config);
const corePermissionItems = permissionItems(PERMISSION_DEFS, permissions);
const extendedPermissionItems = [];
const permissionReadiness = resolvePermissionReadiness(corePermissionItems, extendedPermissionItems);
const permissionSetup = buildPermissionSetupPlan(corePermissionItems, permissionReadiness);
return {
appName: "boss-agent",
generatedAt: now,
device: {
id: nonEmpty(config.deviceId) ?? "local-device",
name: nonEmpty(config.name) ?? os.hostname() ?? "本机电脑",
avatar: nonEmpty(config.avatar) ?? "B",
role: nonEmpty(config.deviceRole) ?? "企业被控节点",
endpoint: nonEmpty(config.endpoint) ?? "mac://local",
},
binding: {
bound,
status: bound ? "bound" : "unbound",
account: bound ? account : "未绑定",
tokenMasked: bound ? maskValue(token) : "",
pairingCode: bound ? "" : nonEmpty(config.pairingCode) ?? "",
qrPayload,
qrExpiresInLabel: bound ? "" : nonEmpty(config.qrExpiresInLabel) ?? "二维码 04:58 后失效",
},
server: {
ok: serverOk,
status: serverOk ? "connected" : "disconnected",
endpoint: nonEmpty(config.controlPlaneUrl) ?? "未配置服务器",
latencyLabel: nonEmpty(config.serverLatencyLabel) ?? (serverOk ? "延迟 28ms" : "连接异常"),
lastHeartbeatAt: nonEmpty(runtime.lastHeartbeatAt) ?? "",
lastHeartbeatStatus: runtime.lastHeartbeatStatus ?? null,
},
api: resolveApiUsage(config),
codex: resolveCodexBinding(config),
agentOta: resolveAgentOta(config, runtime),
license: resolveLicense(config, bound),
permissions: {
summary: permissionReadiness.summary,
items: corePermissionItems,
extendedItems: extendedPermissionItems,
},
permissionReadiness,
permissionSetup,
skills: resolveSkills(runtime),
};
}
function renderPseudoQrSvg(payload) {
const size = 25;
let seed = 0;
for (const char of String(payload || "boss-agent")) {
seed = (seed * 31 + char.charCodeAt(0)) >>> 0;
}
const cells = [];
const finder = (x, y) => x < 7 && y < 7 || x > 17 && y < 7 || x < 7 && y > 17;
for (let y = 0; y < size; y += 1) {
for (let x = 0; x < size; x += 1) {
const finderCell = finder(x, y);
const edge = x === 0 || y === 0 || x === size - 1 || y === size - 1;
const value = finderCell
? !edge && (x % 6 === 1 || y % 6 === 1 || (x % 6 >= 2 && x % 6 <= 4 && y % 6 >= 2 && y % 6 <= 4))
: ((seed + x * 17 + y * 29 + x * y * 7) % 5) < 2;
if (value) {
cells.push(`
${escapeHtml(heroSubtitle)}
${escapeHtml(status.permissionSetup.goal)} 权限结论:${escapeHtml(status.permissions.summary)}。当前状态:${escapeHtml(status.permissionSetup.summary)} 后续静默使用依赖系统持久授权。