feat(runtime): résout react/react-dom vers l'instance host pour les layouts plugin

Le runtime SDK expose désormais react/react-dom résolus contre l'instance
hébergée par IdeA plutôt qu'une copie embarquée, pour que les layouts plugin
en JSX/hooks partagent le même arbre React que l'host. hello-plugin migre son
layout d'exemple en .tsx pour illustrer le contrat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 00:39:25 +02:00
parent 7e1bb5fd38
commit 15f930dd3b
11 changed files with 270 additions and 25 deletions

View File

@ -1,3 +1,5 @@
import type { ComponentType, ReactNode } from "react";
export interface ActivateContext {
pluginId: string;
logger: PluginLogger;
@ -47,7 +49,7 @@ export interface PluginStorage {
export type PluginLayoutState = JsonValue | undefined;
export type PluginLayoutAvailability = "available";
export type PluginLayoutRenderResult = unknown;
export type PluginLayoutRenderResult = ReactNode;
export interface PluginLayoutProps<TState extends PluginLayoutState = PluginLayoutState> {
/** Project currently hosting this layout cell. */
@ -64,9 +66,8 @@ export interface PluginLayoutProps<TState extends PluginLayoutState = PluginLayo
availability: PluginLayoutAvailability;
}
export type PluginLayoutComponent<TState extends PluginLayoutState = PluginLayoutState> = (
props: PluginLayoutProps<TState>,
) => PluginLayoutRenderResult;
export type PluginLayoutComponent<TState extends PluginLayoutState = PluginLayoutState> =
ComponentType<PluginLayoutProps<TState>>;
export interface PluginLayoutDefinition<TState extends PluginLayoutState = PluginLayoutState> {
/** Must match a layout `type` declared in this plugin's manifest. */
@ -87,6 +88,7 @@ export interface PluginServices {
events: EventService;
config: ConfigDocumentService;
terminal: TerminalService;
windows: WindowService;
}
export interface WorkspaceProject {
@ -570,3 +572,32 @@ export interface TerminalService {
/** Kills a PTY by id. */
close(sessionId: string): Promise<void>;
}
export interface OpenPluginWindowOptions {
/** Layout `type` declared by this plugin in `contributes.layouts`. */
layoutType: string;
/** Initial opaque state copied into the detached window surface. */
state?: JsonValue;
}
export interface PluginWindow {
label: string;
url: string;
alreadyOpen: boolean;
providerPluginDisplayName: string;
layoutLabel: string;
surface: {
pluginId: string;
layoutType: string;
state: JsonValue;
};
}
export interface WindowService {
/**
* Opens or focuses a detached IdeA OS window hosting one of this plugin's
* declared layout contributions. The host rejects layout ids absent from this
* plugin's manifest.
*/
open(options: OpenPluginWindowOptions): Promise<PluginWindow>;
}