feat(frontend): système de plugins — runtime, menus, layouts custom (#43)
Lots F1-F4 : runtime de chargement/registre plugin, extension des menus existants, panneau de gestion des plugins, types de layout custom (sélecteur, fallback, cellule dédiée) branchés sur le port plugin. Suite npm typecheck/test verte (947/947). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -45,6 +45,7 @@ import {
|
||||
import {
|
||||
WebDesktopServerGateway,
|
||||
WebFocusedProjectGateway,
|
||||
WebPluginGateway,
|
||||
WebRemoteGateway,
|
||||
WebWindowGateway,
|
||||
} from "./unsupported";
|
||||
@ -139,6 +140,7 @@ export function createHttpWsGateways(config: HttpWsGatewaysConfig = {}): Gateway
|
||||
focusedProject: new WebFocusedProjectGateway(),
|
||||
// Frontend-owned UI prefs are transport-neutral (localStorage) — reuse as-is.
|
||||
uiPreferences: new LocalStorageUiPreferencesGateway(),
|
||||
plugin: new WebPluginGateway(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -116,6 +116,11 @@ export class HttpSystemGateway implements SystemGateway {
|
||||
return unsupportedOnWeb("Native folder picker");
|
||||
}
|
||||
|
||||
pickArchiveFile(): Promise<string | null> {
|
||||
// Desktop-only, same rationale as `pickFolder`.
|
||||
return unsupportedOnWeb("Native file picker");
|
||||
}
|
||||
|
||||
onAppExitWorkGuard(
|
||||
_handler: (state: AppExitWorkGuardState) => void,
|
||||
): Promise<Unsubscribe> {
|
||||
|
||||
@ -12,6 +12,11 @@
|
||||
import type {
|
||||
EmbeddedServerStatus,
|
||||
GatewayError,
|
||||
PluginAdmin,
|
||||
PluginInstallResult,
|
||||
PluginReview,
|
||||
PluginRuntimeContributionCatalog,
|
||||
PluginUninstallResult,
|
||||
ServerExposurePreview,
|
||||
ServerExposureSettings,
|
||||
Unsubscribe,
|
||||
@ -20,7 +25,9 @@ import type {
|
||||
DesktopServerGateway,
|
||||
FocusedProject,
|
||||
FocusedProjectGateway,
|
||||
PluginGateway,
|
||||
RemoteGateway,
|
||||
ReviewPluginPackageInput,
|
||||
ViewWindowClosed,
|
||||
ViewWindowSnapshot,
|
||||
WindowGateway,
|
||||
@ -119,3 +126,37 @@ export class WebDesktopServerGateway implements DesktopServerGateway {
|
||||
return Promise.resolve(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Web stub: the plugin system (#43) installs/loads full-trust local ESM
|
||||
* bundles from the desktop filesystem — no server-side equivalent in V1. The
|
||||
* web client must not manage or load plugins on behalf of the desktop app.
|
||||
*/
|
||||
export class WebPluginGateway implements PluginGateway {
|
||||
async listPlugins(): Promise<PluginAdmin[]> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async reviewPackage(_input: ReviewPluginPackageInput): Promise<PluginReview> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async installFromArchive(_path: string): Promise<PluginInstallResult> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async installFromDirectory(_path: string): Promise<PluginInstallResult> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async setEnabled(_pluginId: string, _enabled: boolean): Promise<PluginAdmin> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async uninstall(_pluginId: string): Promise<PluginUninstallResult> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
async listRuntimeContributions(): Promise<PluginRuntimeContributionCatalog> {
|
||||
// No plugin bundles are ever loaded on the web client — an empty catalog
|
||||
// lets the bootstrap loader run unconditionally without a transport check.
|
||||
return { plugins: [] };
|
||||
}
|
||||
async openPluginsFolder(_pluginId?: string): Promise<void> {
|
||||
return unsupportedOnWeb("Plugin management");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user