Files
openclaw/src/plugin-sdk/browser-maintenance.ts
2026-04-09 08:48:49 +01:00

62 lines
2.0 KiB
TypeScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { generateSecureToken } from "../infra/secure-random.js";
import { runExec } from "../process/exec.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type CloseTrackedBrowserTabsParams = {
sessionKeys: Array<string | undefined>;
closeTab?: (tab: { targetId: string; baseUrl?: string; profile?: string }) => Promise<void>;
onWarn?: (message: string) => void;
};
type BrowserMaintenanceSurface = {
closeTrackedBrowserTabsForSessions: (params: CloseTrackedBrowserTabsParams) => Promise<number>;
};
function hasRequestedSessionKeys(sessionKeys: Array<string | undefined>): boolean {
return sessionKeys.some((key) => Boolean(key?.trim()));
}
function loadBrowserMaintenanceSurface(): BrowserMaintenanceSurface {
return loadBundledPluginPublicSurfaceModuleSync<BrowserMaintenanceSurface>({
dirName: "browser",
artifactBasename: "browser-maintenance.js",
});
}
export async function closeTrackedBrowserTabsForSessions(
params: CloseTrackedBrowserTabsParams,
): Promise<number> {
if (!hasRequestedSessionKeys(params.sessionKeys)) {
return 0;
}
let surface: BrowserMaintenanceSurface;
try {
surface = loadBrowserMaintenanceSurface();
} catch (error) {
params.onWarn?.(`browser cleanup unavailable: ${String(error)}`);
return 0;
}
return await surface.closeTrackedBrowserTabsForSessions(params);
}
export async function movePathToTrash(targetPath: string): Promise<string> {
try {
await runExec("trash", [targetPath], { timeoutMs: 10_000 });
return targetPath;
} catch {
const trashDir = path.join(os.homedir(), ".Trash");
fs.mkdirSync(trashDir, { recursive: true });
const base = path.basename(targetPath);
let dest = path.join(trashDir, `${base}-${Date.now()}`);
if (fs.existsSync(dest)) {
dest = path.join(trashDir, `${base}-${Date.now()}-${generateSecureToken(6)}`);
}
fs.renameSync(targetPath, dest);
return dest;
}
}