152 lines
4.0 KiB
TypeScript
152 lines
4.0 KiB
TypeScript
import type { GamePluginResponse } from "../api/types";
|
|
|
|
export type PluginPermission =
|
|
| "server.create"
|
|
| "server.read"
|
|
| "server.lifecycle"
|
|
| "server.files.read"
|
|
| "server.files.write"
|
|
| "server.logs.read"
|
|
| "server.artifacts.read"
|
|
| "server.artifacts.write"
|
|
| "server.remote.access"
|
|
| "server.run.distribution"
|
|
| "server.dependencies.manage"
|
|
| "server.client-manager.manage"
|
|
| "server.game-client.read"
|
|
| "server.game-client.command"
|
|
| "server.game-client.maintenance"
|
|
| "ai.invoke";
|
|
|
|
export type PluginBridgeAction =
|
|
| "server.instances.read"
|
|
| "jobs.dispatch"
|
|
| "logs.query"
|
|
| "artifacts.open"
|
|
| "files.request"
|
|
| "remote.access.request"
|
|
| "run.distribution.request"
|
|
| "dependencies.request"
|
|
| "logs.backfill.request"
|
|
| "client-manager.request"
|
|
| "plugin-lifecycle.request"
|
|
| "ai.invoke";
|
|
|
|
const pluginPermissions: readonly PluginPermission[] = [
|
|
"server.create",
|
|
"server.read",
|
|
"server.lifecycle",
|
|
"server.files.read",
|
|
"server.files.write",
|
|
"server.logs.read",
|
|
"server.artifacts.read",
|
|
"server.artifacts.write",
|
|
"server.remote.access",
|
|
"server.run.distribution",
|
|
"server.dependencies.manage",
|
|
"server.client-manager.manage",
|
|
"server.game-client.read",
|
|
"server.game-client.command",
|
|
"server.game-client.maintenance",
|
|
"ai.invoke"
|
|
];
|
|
|
|
const pluginBridgeActions: readonly PluginBridgeAction[] = [
|
|
"server.instances.read",
|
|
"jobs.dispatch",
|
|
"logs.query",
|
|
"artifacts.open",
|
|
"files.request",
|
|
"remote.access.request",
|
|
"run.distribution.request",
|
|
"dependencies.request",
|
|
"logs.backfill.request",
|
|
"client-manager.request",
|
|
"plugin-lifecycle.request",
|
|
"ai.invoke"
|
|
];
|
|
|
|
export function isPluginPermission(value: string): value is PluginPermission {
|
|
return pluginPermissions.includes(value as PluginPermission);
|
|
}
|
|
|
|
export function isPluginBridgeAction(value: string): value is PluginBridgeAction {
|
|
return pluginBridgeActions.includes(value as PluginBridgeAction);
|
|
}
|
|
|
|
export interface PluginPageContract {
|
|
key: string;
|
|
title: string;
|
|
path: string;
|
|
bundleKey?: string;
|
|
bundleVersion?: string;
|
|
bundleIntegritySha256?: string;
|
|
permissions?: PluginPermission[];
|
|
bridgeActions?: PluginBridgeAction[];
|
|
}
|
|
|
|
export interface PluginBridgeManifestContract {
|
|
id: string;
|
|
declaredPermissions: PluginPermission[];
|
|
bridgeActions: PluginBridgeAction[];
|
|
pages: PluginPageContract[];
|
|
aiPurposes?: string[];
|
|
}
|
|
|
|
export function pluginBridgeManifestContractFromResponse(
|
|
plugin: Pick<GamePluginResponse, "id" | "declaredPermissions" | "bridgeActions" | "pages" | "aiPurposes">
|
|
): PluginBridgeManifestContract {
|
|
return {
|
|
id: plugin.id,
|
|
declaredPermissions: plugin.declaredPermissions.filter(isPluginPermission),
|
|
bridgeActions: plugin.bridgeActions.filter(isPluginBridgeAction),
|
|
pages: plugin.pages.map((page) => ({
|
|
key: page.key,
|
|
title: page.title,
|
|
path: page.path,
|
|
bundleKey: page.bundleKey,
|
|
bundleVersion: page.bundleVersion,
|
|
bundleIntegritySha256: page.bundleIntegritySha256,
|
|
permissions: page.permissions.filter(isPluginPermission),
|
|
bridgeActions: page.bridgeActions?.filter(isPluginBridgeAction)
|
|
})),
|
|
aiPurposes: [...plugin.aiPurposes]
|
|
};
|
|
}
|
|
|
|
export interface PluginBridgeThemeTokens {
|
|
colorScheme: "light" | "dark";
|
|
accentColor: string;
|
|
}
|
|
|
|
export interface PluginBridgeHostContext {
|
|
pluginId: string;
|
|
routeKey: string;
|
|
serverInstanceId?: string;
|
|
themeTokens: PluginBridgeThemeTokens;
|
|
permissions: PluginPermission[];
|
|
bridgeActions: PluginBridgeAction[];
|
|
aiPurposes: string[];
|
|
}
|
|
|
|
export interface PluginBridgeExecuteEnvelope {
|
|
requestId: string;
|
|
action: PluginBridgeAction;
|
|
aiPurpose?: string;
|
|
payload?: Record<string, string>;
|
|
}
|
|
|
|
export interface PluginBridgeSafeError {
|
|
code: string;
|
|
message: string;
|
|
details?: string[];
|
|
}
|
|
|
|
export interface PluginBridgeExecutionResult {
|
|
requestId: string;
|
|
action: PluginBridgeAction;
|
|
status: "ok" | "queued" | "denied" | "unsupported" | "cancelled" | "error" | string;
|
|
result?: Record<string, string>;
|
|
error?: PluginBridgeSafeError;
|
|
}
|