Rework core integration: validated capability layer, docs, and session state

This commit is contained in:
Fisto
2026-09-11 14:09:04 +02:00
parent 2a15f057df
commit e62d3007d8
33 changed files with 1897 additions and 612 deletions
+1 -9
View File
@@ -25,8 +25,6 @@ export const enum IpcEvents {
GET_SETTINGS = "VCD_GET_SETTINGS",
SET_SETTINGS = "VCD_SET_SETTINGS",
VESKSLOP_GET_TOKEN = "VCD_VESKSLOP_GET_TOKEN",
IS_USING_CUSTOM_VENCORD_DIR = "VCD_IS_USING_CUSTOM_VENCORD_DIR",
SHOW_CUSTOM_VENCORD_DIR = "VCD_SHOW_CUSTOM_VENCORD_DIR",
SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
@@ -85,11 +83,5 @@ export const enum IpcCommands {
GET_LANGUAGES = "navigator.languages",
SCREEN_SHARE_PICKER = "screenshare:picker",
/* Veskslop puppet commands */
STATE_GET = "state:get",
MESSAGE_SEND = "message:send",
MESSAGE_READ = "message:read",
DM_SEND = "dm:send"
SCREEN_SHARE_PICKER = "screenshare:picker"
}
+83
View File
@@ -0,0 +1,83 @@
/*
* Vesktop ⇄ Veskslop daemon protocol.
*
* This is the only surface the external daemon can reach. Every action is
* validated by the core before anything touches Discord, and every failure is
* returned as a structured error instead of throwing.
*/
export const enum PuppetAction {
Ping = "ping",
EventsSubscribe = "events.subscribe",
StateGet = "state.get",
MessageSend = "message.send",
MessageRead = "message.read",
DmSend = "dm.send"
}
export const PuppetActions: readonly PuppetAction[] = [
PuppetAction.Ping,
PuppetAction.EventsSubscribe,
PuppetAction.StateGet,
PuppetAction.MessageSend,
PuppetAction.MessageRead,
PuppetAction.DmSend
];
export const enum PuppetErrorCode {
InvalidRequest = "INVALID_REQUEST",
PayloadTooLarge = "PAYLOAD_TOO_LARGE",
UnknownAction = "UNKNOWN_ACTION",
CoreUnavailable = "CORE_UNAVAILABLE",
NotLoggedIn = "NOT_LOGGED_IN",
InvalidSnowflake = "INVALID_SNOWFLAKE",
InvalidParam = "INVALID_PARAM",
ContentEmpty = "CONTENT_EMPTY",
ContentTooLong = "CONTENT_TOO_LONG",
ChannelNotFound = "CHANNEL_NOT_FOUND",
NotSendable = "NOT_SENDABLE",
SendFailed = "SEND_FAILED",
DmUnavailable = "DM_UNAVAILABLE",
RateLimited = "RATE_LIMITED",
Internal = "INTERNAL"
}
export interface PuppetError {
code: PuppetErrorCode | string;
message: string;
}
export interface PuppetRequest {
id?: string | number;
action: string;
params?: Record<string, unknown>;
}
export type PuppetResult =
| { ok: true; result?: unknown }
| { ok: false; error: PuppetError };
export type PuppetResponse =
| { id?: string | number; ok: true; result?: unknown }
| { id?: string | number; ok: false; error: PuppetError };
export interface PuppetEvent {
type: string;
[key: string]: unknown;
}
/** Hard safety limits applied core-side, regardless of what the daemon asks for. */
export const PUPPET_LIMITS = {
maxContentLength: 2000,
maxReadLimit: 100,
minActionIntervalMs: 500,
maxActionsPerMinute: 30,
maxRequestBytes: 64 * 1024,
maxChannelsPerGuild: 1000
};
const SNOWFLAKE_RE = /^\d{17,20}$/;
export function isSnowflake(value: unknown): value is string {
return typeof value === "string" && SNOWFLAKE_RE.test(value);
}