improve.md still required a retrofit before extending but lost the procedure with retrofit.md. Restore the ordered cuts inline, and fix the stale hook name and plugin-mode wording in skill-author's tests and deployment-modes reference. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.5 KiB
source_keys
| source_keys | |
|---|---|
|
Deployment Modes
Skills deploy standalone, or as part of an APM package (an apm.yml-governed .apm/ tree, compiled via apm compile). Some consumers also receive a package through a host's plugin install, which copies it into a cache. All modes resolve relative paths from the skill root — the SKILL.md body works the same in any of them. Differences only arise when referencing files outside the skill directory.
Cache isolation (host plugin install)
When a host installs a plugin, it copies the plugin directory to a cache. Only the plugin's own files are copied. Any path that leaves the skill directory breaks post-install:
../other-skill/validate.sh # breaks
plugins/<plugin>/.apm/skills/other/ # breaks
../../shared/utils.sh # breaks
Fix: duplicate the file into the skill's own scripts/ or assets/. There is no plugin-level shared/ mechanism — the spec defines no cross-skill sharing, and ../ paths are broken by construction.
Compiled output (APM package mode)
For a package (an apm.yml-governed .apm/ source tree), the deployable artifact is generated by apm compile per target harness — not produced by copying the raw .apm/ directory wholesale the way a plugin cache install copies a plugin directory. The same self-containment rule still applies at the skill level: file references inside .apm/skills/<name>/ must not reach outside that skill's own directory.
../other-skill/validate.sh # breaks
.apm/skills/other-skill/ # breaks
../../shared/utils.sh # breaks
Fix: duplicate the file into the skill's own scripts/ or assets/, same as plugin mode. apm.yml's includes: list (when explicit, not auto) controls what gets published from the package, but it is not a cross-skill sharing mechanism — each skill directory must still stand alone.
Env vars (plugin mode only)
These variables are injected when the plugin is loaded from an install cache. They are not available in standalone mode.
| Variable | Value |
|---|---|
${CLAUDE_PLUGIN_ROOT} |
Absolute path to the plugin's install directory. Changes on update. |
${CLAUDE_PLUGIN_DATA} |
Persistent directory that survives updates. Use for node_modules, generated state, caches. |
Use ${CLAUDE_PLUGIN_ROOT} only in hook commands and .mcp.json configs — not in SKILL.md body text, since standalone deployments won't have it.
Standalone mode
Deployed directly to ~/.agents/skills/<name>/. No plugin context, no env vars injected. All file references must resolve within the skill directory. Skill invocations (e.g. /factory-audit) work if the called skill is also installed.
Cross-tool portability
SKILL.md is portable — the same file works in Claude Code and Copilot CLI, whether deployed standalone or compiled from an APM package. apm.yml is the source manifest: it is itself tool-agnostic (one file describes the package regardless of target), but apm compile produces per-target compiled output — a Claude Code plugin tree, a Copilot CLI tree, etc. — from it. Legacy hand-authored manifest files (plugin.json, hooks.json) are tool-specific and authored separately per tool; they sit outside the apm.yml-based flow.
Shared assets between skills
If two skills in the same plugin need the same file, duplicate it into each skill's assets/ or scripts/. Add a comment in both copies noting the mirror relationship so they stay in sync when the spec changes.