Generated Output
The compiler treats plugin/** as source and everything it writes as a build result. This page explains which paths it owns, what it puts in them, and what happens to files it finds there that the source does not imply.
What the compiler owns
Everything under the plugin directory is authored by you and never rewritten. The compiler owns the whole root skills directory as one tree, so any file inside it that the manifest does not imply is removed on the next compile. Each built-in provider owns exact manifest files: the two Claude manifests, the Codex manifest, the root plugin.json used by Copilot CLI, the Gemini extension manifest, and the Kimi manifest. Every other path in the repository stays outside the write plan and is left untouched.
Ownership comes in two kinds, and the difference matters.
The root skills/ directory is owned as a complete tree. When a schema-v2 plugin has effective hooks for at least one selected provider, hooks/handlers/ is a second complete tree. Hook-free plugins and selections with no compatible hook events claim no shared hook paths. The compiler decides the entire contents of each owned tree. A file you add inside one is reported by check as unexpected and removed by the next compile:
Output check found 2 drift entries:
- skills/NOTES.md: unexpected
- skills/prepare-change-plan/EXTRA.md: unexpectedEach built-in provider owns exact files instead. The compiler writes those specific paths and nothing else, so a provider can never claim an open-ended directory of yours. Custom adapters are held to the same rule: complete-tree ownership is rejected for providers.
Every other path in the repository stays outside the write plan. Source code, tests, documentation, and your own README.md are never read or written.
Generated hooks
The authored plugin/hooks/ tree is copied once to hooks/handlers/, including handler-adjacent internal resources. The compiler also writes hooks/handlers/.runtime/portable-hook-dispatcher.mjs. Compatible provider configurations point at these shared files; handlers are not duplicated per provider.
Native hook configuration remains exact-file-owned by the corresponding adapter. check reports content or missing-file drift in both the shared handler tree and provider-native configuration. Removing every v2 hook makes native config files desired absent and stops claiming the shared handler tree; any prior handler files become unowned rather than being deleted. A selected adapter without compatible hook events receives a structured skip; its ordinary manifest and the shared skills still compile, but no handler resources or empty hook directories are emitted for that selection.
No fallback skill, AGENTS.md, equivalent instruction file, or first-class policy output is generated.
What a generated skill contains
For each published skill the compiler writes skills/<skill-id>/SKILL.md containing, in order:
- Frontmatter derived from the manifest:
nameis the skill ID,descriptionis the manifest description, and an enabled schema-v2disable_model_invocationbecomesdisable-model-invocation: true. Authored sources must not contain frontmatter, so this metadata has exactly one owner. - Your Markdown, unchanged unless its schema-v2 compilation policy inlines Markdown references.
- A
## Required skillssection, one subsection per requirement, with the reason, the instructions, and a relative link to the nested copy. Its position is the marker, when the source has one, and otherwise directly after the title and its introductory paragraphs.
Supporting files that sit next to an authored SKILL.md are copied into the generated skill at the same relative path, so a skill can ship templates, schemas, or reference documents. The source root may be nested below plugin/skills/, but grouping directories are not reproduced: output remains flat at skills/<skill-id>/. The skills/ directory inside any authored skill root is reserved; the compiler builds that directory, and an authored one is rejected.
With compilation.markdown_references: inline, only references/**/*.md files are merged into SKILL.md, in relative-path order, and are not emitted separately. The exact <!-- PLUGIN-COMPILER:MARKDOWN-REFERENCES --> marker chooses their position; otherwise they are appended. Local destinations are rebased from each reference document to the generated skill root. Every non-Markdown reference and all resources outside references/ retain their paths and bytes.
Each required skill is copied into skills/<skill-id>/skills/, recursively, so the dependency exists once in the source and as many times in the output as there are published skills that need it. Skill graph covers the rules that decide which skills become roots and what gets nested.
The generated catalog
skills/README.md shows the dependency graph before listing every published skill with its category, description, visibility, lifecycle status, and replacement:
## Available Skills
Arrows point from a dependent skill to the skill it requires.
```mermaid
flowchart TB
subgraph SkillCategory0["Engineering"]
SkillNode0["`inspect-repository (active/internal)`"]
SkillNode1["`prepare-change-plan (active/public)`"]
end
SkillNode1 --> SkillNode0
```
| Skill | Category | Description | Visibility | Status | Replacement |
| --------------------- | ----------- | -------------------------------------------------------------- | ---------- | ------ | ----------- |
| `prepare-change-plan` | Engineering | Prepare an implementation plan from verified repository facts. | public | Active | — |A deprecated skill appears with its migration guidance in the status column, so the catalog is a truthful index of what the plugin currently offers.
The GitHub-renderable Mermaid graph includes every published root, every transitive required skill that can be reached from those roots, and isolated roots that have no dependencies. Each arrow points from a dependent skill to the skill it requires. Each multiline node label shows the skill's lifecycle status and visibility. Styles distinguish public, internal, and deprecated skills, while category subgraphs show where each skill belongs. Draft, archived, and unreachable internal skills stay out of the graph because they are not part of the published package.
Host manifests
Every selected provider projects the same validated plugin model into its own format. They cannot disagree with each other, because none of them is written by hand. Providers documents each adapter's output.
Provider selection is part of the plan, not a filter applied afterwards. The compiler owns each built-in manifest path whether or not you selected its provider, and a path that no selected provider produces must be absent. Removing codex from providers therefore deletes .codex-plugin/plugin.json on the next compile rather than leaving a stale manifest behind.
That is also why compile reports paths you did not select:
Compilation completed and post-write verification passed.
- .claude-plugin/marketplace.json: changed
- .claude-plugin/plugin.json: changed
- hooks/claude-hooks.json: unchanged
- hooks/codex-hooks.json: unchanged
- hooks/copilot-hooks.json: unchanged
- hooks/handlers: unchanged
- hooks/hooks.json: unchanged
- skills: changed
- .codex-plugin/plugin.json: unchanged
- gemini-extension.json: unchanged
- kimi.plugin.json: unchanged
- plugin.json: unchangedunchanged there means the path is absent and should stay absent.
Determinism
The same authored source compiles to the same bytes: skills are emitted in manifest order, resources and directories in sorted order, and JSON and YAML through fixed formatters. There is no timestamp, no host path, and no random identifier in the output.
Two properties follow from that. Writes are idempotent, so compiling twice changes nothing the second time. And the committed output can be compared with the source, which is what plugin-compiler check does.
Commit the output
Commit generated files with the source. Users install the plugin from the repository, so the output has to be there, and committing it is what lets check prove that it is current. Never fix a generated file by hand: change plugin/** and compile again.
Next steps
- Continuous integration turns
checkinto a build gate. - Providers documents each host manifest.
- CLI reference lists the commands, options, and exit codes.