Files
IdeaSDK/docs/manifest.md

271 lines
7.0 KiB
Markdown

# Manifest
Every plugin package has an `idea-plugin.json` file at the archive root.
For development installs, the same file must exist at the root of the plugin
source directory selected in IdeA with `Paramètres > Plugins > Installer depuis
un dossier…`.
## Minimal Plugin Directory
A plugin directory must contain the manifest at its root and a built ESM
entrypoint matching the manifest `main` field.
```text
my-plugin/
├── idea-plugin.json
├── package.json
├── tsconfig.json
├── src/
│ └── index.ts
└── dist/
└── index.js
```
Create the directory:
```sh
mkdir -p my-plugin/src
cd my-plugin
npm init -y
npm install --save-dev typescript @idea/plugin-sdk
```
Use a package script that emits JavaScript into `dist/`:
```json
{
"type": "module",
"scripts": {
"build": "tsc -p tsconfig.json"
},
"devDependencies": {
"@idea/plugin-sdk": "^0.3.0",
"typescript": "^5.0.0"
}
}
```
When developing against a local SDK checkout instead of a published package,
replace the SDK dependency with a `file:` reference, for example:
```json
{
"devDependencies": {
"@idea/plugin-sdk": "file:../IdeaSDK",
"typescript": "^5.0.0"
}
}
```
Minimal `tsconfig.json`:
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"strict": true
},
"include": ["src"]
}
```
Minimal `src/index.ts`:
```ts
import type { IdeAPluginModule } from "@idea/plugin-sdk";
const plugin: IdeAPluginModule = {
activate(ctx) {
ctx.logger.info("plugin activated", { pluginId: ctx.pluginId });
}
};
export default plugin;
```
Build before installing or reloading:
```sh
npm run build
```
Then install the `my-plugin/` directory in IdeA. For hot reload, keep installing
from the directory, rebuild after source changes, then run `idea_plugin_reload`
for the installed plugin id. Do not install from a ZIP archive for a hot-reload
development loop.
```json
{
"ideaPluginManifestVersion": 1,
"id": "com.example.hello-plugin",
"displayName": "Hello Plugin",
"publisher": "Example",
"version": "0.1.0",
"description": "Example IdeA plugin.",
"main": "dist/index.js",
"engines": {
"idea": ">=0.1.0"
},
"trustLevel": "full",
"capabilities": ["ui", "tooling"],
"activationScope": "app",
"contributes": {
"menus": [],
"menuItems": [],
"layouts": [],
"mcpServers": []
}
}
```
## Required Fields
- `ideaPluginManifestVersion`: currently `1`.
- `id`: stable lowercase id using letters, digits, dots and dashes. It must start
and end with an alphanumeric character.
- `displayName`: human-readable plugin name.
- `version`: semver version.
- `main`: package-relative ESM entrypoint loaded by IdeA.
- `trustLevel`: currently `"full"`.
## Optional Fields
- `description`, `publisher`.
- `engines.idea`: host compatibility hint.
- `activationScope`: `"app"` by default, or `"project"` when activation needs a
focused project immediately.
- `capabilities`: `"ui"`, `"tooling"` and/or `"mcp"`.
## Contributions
`contributes.skills` declares read-only agent skills shipped inside the IdeA
plugin package. These skills are IdeA-native: IdeA can expose them in project
plugin settings, assign them to agents, inject them into the agent skill
catalogue, and serve their Markdown body through `idea_skill_read` for every
supported harness that receives IdeA capabilities, including Claude Code,
Codex, OpenCode local and OpenCode cloud.
```json
{
"contributes": {
"skills": [
{
"id": "unity.build-debug",
"name": "unity-build-debug",
"description": "Diagnose Unity build failures.",
"kind": "workflow",
"path": "skills/unity-build-debug/SKILL.md"
}
]
}
}
```
Skill contribution rules:
- `id` is stable within the plugin and is used by project/agent assignments.
- `name` is the agent-facing name shown in the injected skill catalogue and
accepted by `idea_skill_read`.
- `description` is the short affordance shown before the agent loads the skill.
- `kind` defaults to `"workflow"`; `"reference"` is also supported.
- `path` must be a package-relative Markdown file path ending in `.md`.
- Installing a plugin globally is not enough: a project must enable the plugin,
then assign the skill to the target agent.
See [Project Plugin Assignments](project-plugin-assignments.md) for the
`.ideai/project-plugins.json` schema, validation rules, assignment order, and
agent relaunch requirements.
`contributes.layouts` is the only surface for plugin layouts. The same layout
contribution can be mounted inside an IdeA layout cell or opened in a detached OS
window. Do not add a separate manifest contribution type for windows.
For a command that opens a visible plugin window, declare both the menu command
and the layout type:
```json
{
"ideaPluginManifestVersion": 1,
"id": "com.example.unity-plugin",
"displayName": "Unity Developer Tools",
"publisher": "Example",
"version": "0.1.0",
"description": "Unity integration for IdeA.",
"main": "dist/index.js",
"engines": {
"idea": ">=0.1.0"
},
"trustLevel": "full",
"capabilities": ["ui", "tooling"],
"activationScope": "app",
"contributes": {
"menus": [
{
"id": "unity-plugin.menu",
"label": "Unity Developer Tools",
"topLevel": true,
"order": 100
}
],
"menuItems": [
{
"id": "unity-plugin.health.item",
"targetMenuId": "unity-plugin.menu",
"label": "Health",
"command": "unity-plugin.health",
"order": 10,
"when": "projectOpen"
}
],
"layouts": [
{
"type": "unity-plugin.health",
"label": "Unity Health",
"component": "UnityHealth",
"order": 10
}
]
}
}
```
`capabilities: ["ui"]` is required when a plugin relies on layouts or windows as
human-facing UI. Add `"tooling"` when the same plugin uses workspace, task,
tooling or terminal services. The `contributes.layouts[].type` value is the
public id used by both `ctx.layouts.register({ type, component })` and
`ctx.services.windows.open({ layoutType })`.
Contribution ids are part of the runtime contract:
- commands can only register ids declared by `contributes.menuItems[*].command`;
- layouts can only register `type` values declared by `contributes.layouts`;
- `services.windows.open({ layoutType })` only accepts a layout type declared by
the calling plugin.
## MCP Server Paths
`contributes.mcpServers` entries are resolved by the host before starting a
declared MCP server. In `command`, `args`, `env` and `cwd`, the host expands:
- `${pluginRoot}` to the installed plugin package root.
- `${appDataDir}` to the host-owned application data directory.
This substitution is limited to manifest-declared MCP server startup. It is not
available from `activate(ctx)`, `ctx.services.workspace` or
`ctx.services.tasks.runCommand()`.
## Validation
Use the SDK validator in tests or build tooling:
```ts
import { assertPluginManifest } from "@idea/plugin-sdk";
assertPluginManifest(JSON.parse(manifestText));
```