# Activation And Context The plugin entrypoint exports `activate(ctx)`. ```ts import type { ActivateContext, IdeAPluginModule } from "@idea/plugin-sdk"; export function activate(ctx: ActivateContext): void { ctx.logger.info("activated", { pluginId: ctx.pluginId }); } export default { activate } satisfies IdeAPluginModule; ``` IdeA accepts either a named `activate` export or a default export containing `activate`. ## Activation Scope `activationScope` defaults to `"app"`. App-scoped plugins activate during app bootstrap. Project-scoped plugins are kept pending until a project is focused, then activated once for the app session. Choose `"project"` only when `activate(ctx)` must immediately read project state. Menu commands and layouts can usually stay app-scoped and check for a focused project at invocation/render time. ## Context Fields - `pluginId`, `pluginDisplayName`, `version`: host-provided identity. - `logger`: `debug`, `info`, `warn`, `error`. - `subscriptions`: push disposables returned by command/layout/watch registrations. - `commands`: command registry for declared menu commands. - `layouts`: layout registry for declared layout types. - `menu`: marker for the plugin-owned menu surface. - `storage`: plugin-owned persistent key/value storage. - `services`: public host service facade for plugins declaring `ui` or `tooling` capabilities. The context never exposes internal IdeA gateways or Tauri commands. Use `ctx.services` and the registration APIs instead. ## Disposal Push every returned disposable to `ctx.subscriptions`: ```ts const disposable = ctx.commands?.registerCommand("com.example.run", run); if (disposable) ctx.subscriptions.push(disposable); ``` IdeA disposes these handles best-effort when the plugin is unloaded or the app session ends. ## Storage Use `ctx.storage` for plugin-owned counters, flags, preferences and small caches. Use workspace/config services only for project-owned files or configuration that the user expects to see in the project.