From e509e796b4acb18e90e6f159d702088789521dbb Mon Sep 17 00:00:00 2001 From: Blomios Date: Mon, 3 Aug 2026 14:43:23 +0200 Subject: [PATCH] feat(sdk): add plugin activationScope (app/project) Manifests can now declare activationScope to defer activation until a project is focused, instead of always activating at app bootstrap. Co-Authored-By: Claude Sonnet 5 --- README.md | 7 +++++++ src/index.ts | 1 + src/manifest.ts | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/README.md b/README.md index f81aaab..50a1949 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,17 @@ TypeScript. "version": "0.1.0", "main": "dist/index.js", "trustLevel": "full", + "activationScope": "app", "contributes": {} } ``` +`activationScope` is optional and defaults to `"app"`, which activates the +plugin at app bootstrap without requiring a focused project. Use +`"activationScope": "project"` only when `activate(ctx)` needs project-scoped +services immediately; IdeA will keep that plugin pending until a project is +focused, then activate it once for the app session. + The `main` field is the ESM entrypoint loaded by IdeA. It may import other JavaScript files from the same plugin package with relative specifiers: diff --git a/src/index.ts b/src/index.ts index 3defaa2..be8b304 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ export type { + IdeAPluginActivationScope, IdeAPluginCapability, IdeAPluginManifest, IdeAPluginEngineConstraints, diff --git a/src/manifest.ts b/src/manifest.ts index 3b33509..c3d4e6d 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -9,6 +9,10 @@ export interface IdeAPluginManifest { publisher?: string; engines?: IdeAPluginEngineConstraints; capabilities?: IdeAPluginCapability[]; + /** + * Defaults to "app". Use "project" when activate(ctx) requires a focused project. + */ + activationScope?: IdeAPluginActivationScope; contributes?: { menus?: IdeAPluginTopLevelMenuContribution[]; menuItems?: IdeAPluginMenuItemContribution[]; @@ -19,6 +23,8 @@ export interface IdeAPluginManifest { export type IdeAPluginCapability = "ui" | "mcp" | "tooling"; +export type IdeAPluginActivationScope = "app" | "project"; + export interface IdeAPluginEngineConstraints { idea?: string; } @@ -100,6 +106,7 @@ export function validatePluginManifest(input: unknown): PluginManifestValidation validateEngines(input.engines, errors); validateCapabilities(input.capabilities, errors); + validateActivationScope(input.activationScope, errors); validateContributes(input.contributes, errors); if (errors.length > 0) { @@ -151,6 +158,16 @@ function validateCapabilities(value: unknown, errors: string[]): void { }); } +function validateActivationScope(value: unknown, errors: string[]): void { + if (value === undefined) { + return; + } + + if (value !== "app" && value !== "project") { + errors.push("activationScope must be \"app\" or \"project\" when provided"); + } +} + function validateContributes(value: unknown, errors: string[]): void { if (value === undefined) { return;