diff --git a/README.md b/README.md index 1b7adfe..b128307 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/codex-skills-and-idea-plugins.md b/docs/codex-skills-and-idea-plugins.md index 59c1693..8767531 100644 --- a/docs/codex-skills-and-idea-plugins.md +++ b/docs/codex-skills-and-idea-plugins.md @@ -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//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. diff --git a/docs/manifest.md b/docs/manifest.md index ebaf2de..56f2727 100644 --- a/docs/manifest.md +++ b/docs/manifest.md @@ -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. diff --git a/src/index.ts b/src/index.ts index fb39ad6..3ae4698 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,8 @@ export type { IdeAPluginLayoutContribution, IdeAPluginMcpServerContribution, IdeAPluginMenuItemContribution, + IdeAPluginSkillContribution, + IdeAPluginSkillKind, IdeAPluginTopLevelMenuContribution } from "./manifest.js"; export { diff --git a/src/manifest.ts b/src/manifest.ts index 126aa30..d576ce5 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -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//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`);