feat(sdk): contributes.skills — skills IdeA-native déclarables par plugin — #282 (types IdeAPluginSkillContribution/IdeAPluginSkillKind: id/name/description/kind workflow|reference/path .md package-relative, validation manifeste, export public; docs manifest + codex-skills-and-idea-plugins recentrés skills IdeA-native vs .codex-plugin Codex, README; QA verte: npm run build)

This commit is contained in:
2026-09-08 15:48:47 +02:00
parent 1239104b0f
commit 6eb8db3791
5 changed files with 101 additions and 26 deletions

View File

@ -16,7 +16,7 @@ exports `activate(ctx)`.
- [Windows](docs/windows.md): opening plugin layouts in detached OS windows.
- [Services](docs/services.md): workspace, tasks, tooling, events, config, terminal and windows facades.
- [Packaging And Distribution](docs/packaging-distribution.md): build output, archive layout, hot reload and dependency rules.
- [Codex Skills And IdeA Plugins](docs/codex-skills-and-idea-plugins.md): separate runtime install from Codex skill discovery.
- [Codex Skills And IdeA Plugins](docs/codex-skills-and-idea-plugins.md): separate IdeA-native plugin skills from Codex plugin discovery.
The installable example lives in [`examples/hello-plugin`](examples/hello-plugin).
It demonstrates a menu command, storage, background-task feedback, a React layout

View File

@ -1,12 +1,20 @@
# Codex Skills And IdeA Plugins
IdeA runtime plugins and Codex plugins are separate installation and discovery
systems.
IdeA runtime plugins, IdeA-native plugin skills and Codex plugins are distinct
installation and discovery systems.
An IdeA runtime plugin is described by `idea-plugin.json`. Installing it through
IdeA makes its IdeA runtime contributions available: menus, menu items, slash
commands, layouts, MCP servers and runtime services declared by the IdeA plugin
manifest.
IdeA makes its global runtime package available. Project settings then decide
which installed plugins are enabled for a project, and agent settings decide
which plugin skills and plugin MCP tools are assigned to each agent.
An IdeA-native plugin skill is declared in `idea-plugin.json` under
`contributes.skills`. Its body is a package-relative Markdown file such as
`skills/<name>/SKILL.md`. When the plugin is enabled for a project and the skill
is assigned to an agent, IdeA injects the skill affordance into that agent's
skill catalogue and serves the body through `idea_skill_read`. This is not
Codex-specific; it is projected by IdeA for every harness that supports IdeA
capabilities, including Claude Code, Codex, OpenCode local and OpenCode cloud.
A Codex plugin is described by `.codex-plugin/plugin.json`. Its `skills` entry
points Codex at skill directories such as `skills/*/SKILL.md`. This metadata is
@ -15,27 +23,29 @@ loading.
## Normative Behavior
- Installing or reloading an IdeA plugin makes the package available globally,
but does not automatically enable it in every project.
- Enabling a plugin for a project does not automatically assign every skill or
MCP tool to every agent.
- A plugin skill becomes visible to an agent only when the plugin is enabled for
the project and that skill is assigned to that agent.
- Installing or reloading an IdeA plugin does not automatically install a bundled
Codex plugin.
- Installing or reloading an IdeA plugin does not automatically make bundled
Codex skills available to agents in the current project.
- Installing or reloading an IdeA plugin does not automatically make bundled
Codex skills available to agents in other projects.
- No `idea-plugin.json` manifest field currently declares Codex skills for IdeA
agent assignment.
- Bundling `.codex-plugin/plugin.json` and `skills/*/SKILL.md` inside an IdeA
plugin package is allowed as distribution content, but it is inert for IdeA
runtime plugin loading unless a separate bridge explicitly consumes it.
Codex plugin, and `.codex-plugin/plugin.json` remains inert for IdeA-native
plugin loading unless a separate bridge explicitly consumes it.
- Bundling `.codex-plugin/plugin.json` is still allowed as distribution content
for Codex-specific workflows, but it is not the multi-harness IdeA contract.
## Required Mechanism
## Required Mechanisms
If a plugin needs Codex skills to be available to agents, install the Codex
plugin through the Codex plugin mechanism for the intended scope, then assign or
enable those skills for the relevant agents according to Codex/IdeA agent
configuration.
For multi-harness IdeA agent skills, declare `contributes.skills` in
`idea-plugin.json`, ship the referenced Markdown files inside the package,
install the plugin in IdeA, enable it in the target project, and assign the
skills to the target agents.
Do not rely on IdeA plugin installation as a cross-project skill propagation
mechanism. Cross-project skill availability needs an explicit product contract
covering scope, provenance, permissions, uninstall behavior, hot reload,
collisions and security. Until that bridge exists, document and perform Codex
skill installation separately from IdeA runtime plugin installation.
For Codex-specific plugin skills, install the Codex plugin through the Codex
plugin mechanism for the intended scope, then assign or enable those skills
according to Codex/IdeA agent configuration.
Do not rely on `.codex-plugin/plugin.json` as a cross-harness skill propagation
mechanism. Cross-harness plugin skill availability is driven by
`idea-plugin.json` and IdeA project/agent assignments.

View File

@ -143,6 +143,40 @@ development loop.
## 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.
`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.

View File

@ -6,6 +6,8 @@ export type {
IdeAPluginLayoutContribution,
IdeAPluginMcpServerContribution,
IdeAPluginMenuItemContribution,
IdeAPluginSkillContribution,
IdeAPluginSkillKind,
IdeAPluginTopLevelMenuContribution
} from "./manifest.js";
export {

View File

@ -14,6 +14,7 @@ export interface IdeAPluginManifest {
*/
activationScope?: IdeAPluginActivationScope;
contributes?: {
skills?: IdeAPluginSkillContribution[];
menus?: IdeAPluginTopLevelMenuContribution[];
menuItems?: IdeAPluginMenuItemContribution[];
slashCommands?: IdeAPluginSlashCommandContribution[];
@ -26,10 +27,24 @@ export type IdeAPluginCapability = "ui" | "mcp" | "tooling";
export type IdeAPluginActivationScope = "app" | "project";
export type IdeAPluginSkillKind = "workflow" | "reference";
export interface IdeAPluginEngineConstraints {
idea?: string;
}
export interface IdeAPluginSkillContribution {
id: string;
/** Agent-facing name shown in the injected skill catalogue and accepted by idea_skill_read. */
name: string;
/** Short affordance shown to agents before they load the skill body. */
description: string;
/** Defaults to "workflow". */
kind?: IdeAPluginSkillKind;
/** Package-relative Markdown file, usually skills/<name>/SKILL.md. */
path: string;
}
export interface IdeAPluginTopLevelMenuContribution {
id: string;
label: string;
@ -192,6 +207,20 @@ function validateContributes(value: unknown, errors: string[]): void {
return;
}
validateArray(value, "skills", errors, (skill, index) => {
requireString(skill, "id", errors, `contributes.skills[${index}].id`);
requireString(skill, "name", errors, `contributes.skills[${index}].name`);
requireString(skill, "description", errors, `contributes.skills[${index}].description`);
requireString(skill, "path", errors, `contributes.skills[${index}].path`);
if (typeof skill.kind === "string" && skill.kind !== "workflow" && skill.kind !== "reference") {
errors.push(`contributes.skills[${index}].kind must be "workflow" or "reference" when provided`);
} else if (skill.kind !== undefined && typeof skill.kind !== "string") {
errors.push(`contributes.skills[${index}].kind must be a string when provided`);
}
if (typeof skill.path === "string" && !skill.path.endsWith(".md")) {
errors.push(`contributes.skills[${index}].path must point to a .md file`);
}
});
validateArray(value, "menus", errors, (menu, index) => {
requireString(menu, "id", errors, `contributes.menus[${index}].id`);
requireString(menu, "label", errors, `contributes.menus[${index}].label`);