源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)

This commit is contained in:
agent-radar
2026-09-02 01:05:41 +08:00
commit 04bac1f6e2
2200 changed files with 489415 additions and 0 deletions
@@ -0,0 +1,589 @@
import { execFile } from "node:child_process";
import { constants as fsConstants } from "node:fs";
import {
access,
copyFile,
mkdir,
readFile,
readdir,
rename,
rm,
writeFile,
} from "node:fs/promises";
import os from "node:os";
import path from "node:path";
/** @typedef {import("@openwork/types/desktop-ipc").DesktopIntegrationIssue} DesktopIntegrationIssue */
/** @typedef {import("@openwork/types/desktop-ipc").DesktopIntegrationResult} DesktopIntegrationResult */
/** @typedef {import("@openwork/types/desktop-ipc").DesktopIntegrationStatus} DesktopIntegrationStatus */
export const OPENWORK_DESKTOP_ID = "com.differentai.openwork.desktop";
export const OPENWORK_DESKTOP_NAME = "com.differentai.openwork";
export const OPENWORK_PROTOCOL_MIME = "x-scheme-handler/openwork";
const INTEGRATION_STATE_VERSION = 1;
const OWNERSHIP_MARKER = "X-OpenWork-Managed";
const MANAGED_VERSION_MARKER = "X-OpenWork-Version";
const ICON_SIZES = [16, 24, 32, 48, 64, 96, 128, 256, 512];
function defaultCommandRunner(command, args) {
return new Promise((resolve) => {
execFile(command, args, { encoding: "utf8", timeout: 10_000 }, (error, stdout, stderr) => {
resolve({
ok: !error,
stdout: typeof stdout === "string" ? stdout : "",
stderr: typeof stderr === "string" ? stderr : error?.message ?? "",
});
});
});
}
function cleanDesktopValue(value) {
return String(value ?? "").replace(/[\0\r\n]/g, " ").trim();
}
export function quoteDesktopExec(value) {
const cleaned = cleanDesktopValue(value);
const quoted = cleaned
.replaceAll("%", "%%")
.replace(/([\\`"$])/g, "\\$1");
return `"${quoted}"`;
}
function parseDesktopEntry(content) {
const fields = new Map();
let inDesktopEntry = false;
for (const rawLine of String(content ?? "").split(/\r?\n/)) {
const line = rawLine.trim();
if (line.startsWith("[") && line.endsWith("]")) {
inDesktopEntry = line === "[Desktop Entry]";
continue;
}
if (!inDesktopEntry || !line || line.startsWith("#")) continue;
const separator = line.indexOf("=");
if (separator <= 0) continue;
fields.set(line.slice(0, separator).trim(), line.slice(separator + 1).trim());
}
return fields;
}
function unquoteDesktopValue(value) {
const trimmed = String(value ?? "").trim();
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
return trimmed.slice(1, -1).replace(/\\([\\`"$])/g, "$1");
}
if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
return trimmed.slice(1, -1);
}
return trimmed;
}
function entryTargetsAppImage(fields, appImagePath) {
const tryExec = unquoteDesktopValue(fields.get("TryExec"));
if (tryExec && path.resolve(tryExec) === appImagePath) return true;
const exec = fields.get("Exec") ?? "";
return exec.includes(appImagePath)
|| exec.includes(quoteDesktopExec(appImagePath))
|| exec.includes(`'${appImagePath.replaceAll("'", "'\\''")}'`);
}
function entryHandlesOpenwork(fields) {
return (fields.get("MimeType") ?? "")
.split(";")
.map((value) => value.trim())
.includes(OPENWORK_PROTOCOL_MIME);
}
function entryAcceptsUrl(fields) {
return /%(?:u|U)(?:\s|$)/.test(fields.get("Exec") ?? "");
}
function emptyState() {
return {
version: INTEGRATION_STATE_VERSION,
dismissedAppImages: [],
previousProtocolHandler: null,
};
}
function normalizeState(value) {
if (!value || typeof value !== "object") return emptyState();
const dismissed = Array.isArray(value.dismissedAppImages)
? value.dismissedAppImages.filter((item) => typeof item === "string")
: [];
return {
version: INTEGRATION_STATE_VERSION,
dismissedAppImages: dismissed,
previousProtocolHandler:
typeof value.previousProtocolHandler === "string" && value.previousProtocolHandler.trim()
? value.previousProtocolHandler.trim()
: null,
};
}
async function fileExists(target) {
return access(target, fsConstants.F_OK).then(() => true).catch(() => false);
}
async function atomicWrite(target, content) {
const temporary = `${target}.${process.pid}.${Date.now()}.tmp`;
await mkdir(path.dirname(target), { recursive: true });
await writeFile(temporary, content, { encoding: "utf8", mode: 0o644 });
await rename(temporary, target);
}
async function removeDesktopAssociation(filePath, desktopId) {
const content = await readFile(filePath, "utf8").catch(() => null);
if (content == null) return false;
let section = "";
let changed = false;
const next = content.split(/\r?\n/).map((line) => {
const trimmed = line.trim();
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
section = trimmed;
return line;
}
if (
(section !== "[Default Applications]" && section !== "[Added Associations]")
|| !trimmed.startsWith(`${OPENWORK_PROTOCOL_MIME}=`)
) {
return line;
}
const separator = line.indexOf("=");
const handlers = line
.slice(separator + 1)
.split(";")
.map((value) => value.trim())
.filter((value) => value && value !== desktopId);
changed = true;
return `${line.slice(0, separator + 1)}${handlers.length ? `${handlers.join(";")};` : ""}`;
}).join("\n");
if (changed) await atomicWrite(filePath, next);
return changed;
}
/** @returns {DesktopIntegrationStatus} */
function unsupportedStatus() {
return {
supported: false,
state: "unsupported",
ownership: "none",
appImagePath: null,
desktopEntryPath: null,
handlerDesktopId: null,
issues: [],
};
}
export function buildOpenworkDesktopEntry({
appImagePath,
appName,
appVersion,
distribution,
}) {
return `[Desktop Entry]
Type=Application
Version=1.0
Name=${cleanDesktopValue(appName)}
Comment=Run agents, skills, and MCP with OpenWork
Exec=${quoteDesktopExec(appImagePath)} %U
TryExec=${cleanDesktopValue(appImagePath)}
Icon=${OPENWORK_DESKTOP_NAME}
StartupWMClass=${OPENWORK_DESKTOP_NAME}
Terminal=false
Categories=Development;Utility;
MimeType=${OPENWORK_PROTOCOL_MIME};
X-AppImage-Name=${cleanDesktopValue(appName)}
X-AppImage-Version=${cleanDesktopValue(appVersion)}
${OWNERSHIP_MARKER}=true
${MANAGED_VERSION_MARKER}=${cleanDesktopValue(appVersion)}
X-OpenWork-Distribution=${cleanDesktopValue(distribution)}
X-OpenWork-AppImage=${cleanDesktopValue(appImagePath)}
`;
}
export function createLinuxDesktopIntegration({
app,
dialog,
appName,
distribution,
env = process.env,
platform = process.platform,
homeDir = os.homedir(),
resourcesPath = process.resourcesPath,
runCommand = defaultCommandRunner,
}) {
const rawAppImagePath = typeof env.APPIMAGE === "string" ? env.APPIMAGE.trim() : "";
const appImagePath = rawAppImagePath && path.isAbsolute(rawAppImagePath)
? path.resolve(rawAppImagePath)
: null;
const supported = platform === "linux" && app.isPackaged && appImagePath != null;
const dataHome = env.XDG_DATA_HOME?.trim() || path.join(homeDir, ".local", "share");
const configHome = env.XDG_CONFIG_HOME?.trim() || path.join(homeDir, ".config");
const desktopEntryPath = path.join(dataHome, "applications", OPENWORK_DESKTOP_ID);
const iconPaths = Object.fromEntries(ICON_SIZES.map((size) => [
size,
path.join(dataHome, "icons", "hicolor", `${size}x${size}`, "apps", `${OPENWORK_DESKTOP_NAME}.png`),
]));
const iconSources = Object.fromEntries(ICON_SIZES.map((size) => [
size,
path.join(resourcesPath ?? "", "icons", "linux", `${size}x${size}.png`),
]));
const statePath = path.join(configHome, "openwork", "desktop-integration.json");
async function readState() {
const raw = await readFile(statePath, "utf8").catch(() => null);
if (raw == null) return emptyState();
try {
return normalizeState(JSON.parse(raw));
} catch {
return emptyState();
}
}
async function writeState(state) {
await atomicWrite(statePath, `${JSON.stringify(normalizeState(state), null, 2)}\n`);
}
async function queryDefaultHandler() {
const result = await runCommand("xdg-mime", ["query", "default", OPENWORK_PROTOCOL_MIME]);
return result.ok && result.stdout.trim() ? result.stdout.trim() : null;
}
function desktopSearchRoots() {
const systemRoots = (env.XDG_DATA_DIRS?.trim() || "/usr/local/share:/usr/share")
.split(":")
.filter(Boolean);
return [dataHome, ...systemRoots].map((root) => path.join(root, "applications"));
}
async function locateDesktopEntry(desktopId) {
if (!desktopId || desktopId.includes("/") || desktopId.includes("\\")) return null;
for (const root of desktopSearchRoots()) {
const candidate = path.join(root, desktopId);
if (await fileExists(candidate)) return candidate;
}
return null;
}
async function inspectDesktopFile(candidate, desktopId) {
const content = await readFile(candidate, "utf8").catch(() => null);
if (content == null) return null;
const fields = parseDesktopEntry(content);
if (!entryTargetsAppImage(fields, appImagePath)) return null;
return {
desktopId,
path: candidate,
managed: fields.get(OWNERSHIP_MARKER) === "true",
acceptsUrl: entryAcceptsUrl(fields),
handlesProtocol: entryHandlesOpenwork(fields),
};
}
async function findExternalEntry(handlerDesktopId) {
const inspected = handlerDesktopId
? await locateDesktopEntry(handlerDesktopId)
.then((candidate) => candidate && inspectDesktopFile(candidate, handlerDesktopId))
: null;
if (inspected && !inspected.managed) return inspected;
const applicationsRoot = path.join(dataHome, "applications");
const entries = await readdir(applicationsRoot, { withFileTypes: true }).catch(() => []);
for (const entry of entries) {
if (!entry.isFile() || !entry.name.endsWith(".desktop") || entry.name === OPENWORK_DESKTOP_ID) continue;
const candidate = await inspectDesktopFile(path.join(applicationsRoot, entry.name), entry.name);
if (candidate && !candidate.managed) return candidate;
}
return null;
}
/** @returns {Promise<DesktopIntegrationStatus>} */
async function getStatus() {
if (!supported) return unsupportedStatus();
const handlerDesktopId = await queryDefaultHandler();
const ownContent = await readFile(desktopEntryPath, "utf8").catch(() => null);
const ownFields = ownContent == null ? null : parseDesktopEntry(ownContent);
const ownManaged = ownFields?.get(OWNERSHIP_MARKER) === "true";
if (ownFields && ownManaged) {
/** @type {DesktopIntegrationIssue[]} */
const issues = [];
if (!entryTargetsAppImage(ownFields, appImagePath)) issues.push("appimage-path");
if (!entryHandlesOpenwork(ownFields)) issues.push("desktop-entry");
if (ownFields.get(MANAGED_VERSION_MARKER) !== app.getVersion()) issues.push("version");
const iconsPresent = await Promise.all(
ICON_SIZES.map((size) => fileExists(iconPaths[size])),
);
if (!iconsPresent.every(Boolean)) issues.push("icon");
if (handlerDesktopId !== OPENWORK_DESKTOP_ID) issues.push("protocol-handler");
return {
supported: true,
state: issues.length ? "needs_repair" : "integrated",
ownership: "openwork",
appImagePath,
desktopEntryPath,
handlerDesktopId,
issues,
};
}
const external = await findExternalEntry(handlerDesktopId);
if (external) {
/** @type {DesktopIntegrationIssue[]} */
const issues = [];
if (!external.acceptsUrl || !external.handlesProtocol) issues.push("desktop-entry");
if (handlerDesktopId !== external.desktopId) issues.push("protocol-handler");
return {
supported: true,
state: issues.length ? "needs_repair" : "managed_externally",
ownership: "external",
appImagePath,
desktopEntryPath: external.path,
handlerDesktopId,
issues,
};
}
return {
supported: true,
state: "not_integrated",
ownership: "none",
appImagePath,
desktopEntryPath: null,
handlerDesktopId,
issues: ["desktop-entry", "icon", "protocol-handler"],
};
}
async function refreshDesktopCaches() {
await runCommand("update-desktop-database", [path.join(dataHome, "applications")]);
await runCommand("gtk-update-icon-cache", ["-f", "-t", path.join(dataHome, "icons", "hicolor")]);
}
/**
* @param {{ useExternalLauncher?: boolean }} [options]
* @returns {Promise<DesktopIntegrationResult>}
*/
async function install(options = {}) {
if (!supported) {
return { ok: false, status: unsupportedStatus(), error: "Desktop integration is available only for packaged Linux AppImages." };
}
const before = await getStatus();
if (before.ownership === "external" && options.useExternalLauncher !== true) {
return {
ok: false,
status: before,
error: "This AppImage is managed by an external integration tool.",
};
}
if (before.ownership === "external") {
if (before.issues.includes("desktop-entry")) {
return {
ok: false,
status: before,
error: "The external launcher cannot accept browser callback URLs. Repair it with the tool that manages this AppImage.",
};
}
if (!before.desktopEntryPath) {
return {
ok: false,
status: before,
error: "The external launcher path is unavailable.",
};
}
const registration = await runCommand("xdg-mime", [
"default",
path.basename(before.desktopEntryPath),
OPENWORK_PROTOCOL_MIME,
]);
if (!registration.ok) {
return {
ok: false,
status: await getStatus(),
error: registration.stderr || "xdg-mime could not register the external launcher.",
};
}
const status = await getStatus();
if (status.state === "managed_externally") return { ok: true, status };
return {
ok: false,
status,
error: "The external launcher was not selected for openwork:// callbacks.",
};
}
if (
await fileExists(desktopEntryPath)
&& before.ownership !== "openwork"
) {
return {
ok: false,
status: before,
error: "The canonical OpenWork launcher is externally managed and will not be overwritten.",
};
}
try {
for (const size of ICON_SIZES) {
await mkdir(path.dirname(iconPaths[size]), { recursive: true });
await copyFile(iconSources[size], iconPaths[size]);
}
await atomicWrite(desktopEntryPath, buildOpenworkDesktopEntry({
appImagePath,
appName,
appVersion: app.getVersion(),
distribution,
}));
const state = await readState();
if (before.handlerDesktopId && before.handlerDesktopId !== OPENWORK_DESKTOP_ID) {
state.previousProtocolHandler = before.handlerDesktopId;
}
state.dismissedAppImages = state.dismissedAppImages.filter((candidate) => candidate !== appImagePath);
await writeState(state);
await refreshDesktopCaches();
const registration = await runCommand("xdg-mime", ["default", OPENWORK_DESKTOP_ID, OPENWORK_PROTOCOL_MIME]);
if (!registration.ok) {
throw new Error(registration.stderr || "xdg-mime could not register openwork://.");
}
const status = await getStatus();
if (status.state !== "integrated") {
throw new Error("The desktop entry was installed, but the desktop did not select it as the openwork:// handler.");
}
return { ok: true, status };
} catch (error) {
return {
ok: false,
status: await getStatus(),
error: error instanceof Error ? error.message : String(error),
};
}
}
/** @returns {Promise<DesktopIntegrationResult>} */
async function remove() {
if (!supported) {
return { ok: false, status: unsupportedStatus(), error: "Desktop integration is unavailable." };
}
const before = await getStatus();
if (before.ownership !== "openwork") {
return {
ok: false,
status: before,
error: before.ownership === "external"
? "Remove this AppImage with the tool that manages it."
: "OpenWork does not own a desktop integration to remove.",
};
}
try {
const state = await readState();
await rm(desktopEntryPath, { force: true });
await Promise.all(Object.values(iconPaths).map((target) => rm(target, { force: true })));
if (before.handlerDesktopId === OPENWORK_DESKTOP_ID) {
const previousPath = await locateDesktopEntry(state.previousProtocolHandler);
if (state.previousProtocolHandler && previousPath) {
await runCommand("xdg-mime", ["default", state.previousProtocolHandler, OPENWORK_PROTOCOL_MIME]);
} else {
await removeDesktopAssociation(path.join(configHome, "mimeapps.list"), OPENWORK_DESKTOP_ID);
await removeDesktopAssociation(path.join(dataHome, "applications", "mimeapps.list"), OPENWORK_DESKTOP_ID);
}
}
state.previousProtocolHandler = null;
if (!state.dismissedAppImages.includes(appImagePath)) state.dismissedAppImages.push(appImagePath);
await writeState(state);
await refreshDesktopCaches();
return { ok: true, status: await getStatus() };
} catch (error) {
return {
ok: false,
status: await getStatus(),
error: error instanceof Error ? error.message : String(error),
};
}
}
async function shouldSkipPrompt() {
if (!supported) return true;
const state = await readState();
return state.dismissedAppImages.includes(appImagePath);
}
async function rememberPromptDismissal() {
if (!supported) return;
const state = await readState();
if (!state.dismissedAppImages.includes(appImagePath)) state.dismissedAppImages.push(appImagePath);
await writeState(state);
}
async function maybePrompt(window) {
const status = await getStatus();
if (
!status.supported
|| status.state === "integrated"
|| status.state === "managed_externally"
|| status.ownership === "external"
) {
return status;
}
// The user already accepted this integration, so drift in the files OpenWork
// owns is maintenance rather than a new decision. A self-update lands under a
// new versioned filename and a moved AppImage changes its path; both stale the
// launcher. Repair silently instead of prompting after every release.
if (status.ownership === "openwork") {
const repaired = await install();
if (!repaired.ok) {
console.warn("[desktop-integration] silent repair failed", repaired.error);
}
return repaired.status;
}
if (await shouldSkipPrompt()) return status;
const { response, checkboxChecked } = await dialog.showMessageBox(window, {
type: "question",
title: "Add OpenWork to your applications?",
message: "Add OpenWork to your application launcher and register browser sign-in callbacks?",
detail: `The launcher will use this AppImage in its current location:\n${appImagePath}\n\nIf you move or update it later, OpenWork repairs the launcher automatically. You can change or remove this in Settings → Preferences → AppImage desktop integration.`,
buttons: ["Not now", "Integrate"],
defaultId: 1,
cancelId: 0,
checkboxLabel: "Don’t ask again for this AppImage",
checkboxChecked: false,
});
if (response !== 1) {
if (checkboxChecked) await rememberPromptDismissal();
return status;
}
const result = await install();
if (!result.ok) {
await dialog.showMessageBox(window, {
type: "warning",
title: "Desktop integration failed",
message: "OpenWork could not complete desktop integration.",
detail: result.error ?? "Unknown error",
buttons: ["OK"],
});
}
return result.status;
}
return {
getStatus,
install,
remove,
maybePrompt,
paths: {
dataHome,
configHome,
desktopEntryPath,
iconPaths,
statePath,
},
};
}