diff --git a/docs/menus.md b/docs/menus.md index 19b638c..ff97f65 100644 --- a/docs/menus.md +++ b/docs/menus.md @@ -44,6 +44,10 @@ export function activate(ctx: ActivateContext): void { - A command can only be registered if at least one manifest menu item declares that exact `command` id. - Missing command handlers are a no-op when the user clicks the menu item. +- A registered handler's rejected promise is not swallowed: the host logs the + plugin id, command id and reason, then presents a retryable error. In + particular, return/await `services.windows.open(...)` so native-window + failures follow this path. - A handler owns precondition checks and feedback. See [Commands And Feedback](commands-and-feedback.md). - Menu item `when` expressions are evaluated by the host; unsupported or false diff --git a/docs/windows.md b/docs/windows.md index 7ff1ae4..17468c8 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -24,6 +24,13 @@ do not currently guarantee that return value is displayed. existing `contributes.layouts` layout. - The host validates the plugin is runtime-active and the layout exists before opening or focusing the window. +- The calling plugin package must still be installed, enabled globally and + enabled for the focused project. A stale command from a replaced runtime is + rejected instead of opening a window under another plugin's identity. +- `windows.open(...)` rejects its promise when any validation or native-window + operation fails. Let that rejection reach the command handler (or catch it, + log it and return explicit failed feedback); the IdeA menu host logs the + rejection and shows a retryable error to the user. - Reopening the same plugin/layout pair focuses the existing window. - `state` is JSON-serializable initial window state. The mounted component can later call `setState(next)` to update its local host state. @@ -47,13 +54,14 @@ The returned `label` is a host-owned window identity. Treat it as opaque. ```ts ctx.commands?.registerCommand("hello-plugin.open-dashboard", async () => { - const win = await ctx.services?.windows.open({ + if (!ctx.services) { + return { status: "skipped", reason: "ui-service-unavailable", message: "UI service unavailable." }; + } + const win = await ctx.services.windows.open({ layoutType: "hello-plugin.dashboard", state: { source: "menu" } }); - return win - ? { status: "opened", message: "Opened dashboard.", alreadyOpen: win.alreadyOpen } - : { status: "skipped", reason: "ui-service-unavailable", message: "UI service unavailable." }; + return { status: "opened", message: "Opened dashboard.", alreadyOpen: win.alreadyOpen }; }); ```