Skip to main content

Targets

The 77 runtimes, the two scopes, and where each artifact lands on disk.

Where a skill lands is a function of three things, the artifact type, the runtime you named, and the scope you are writing in. This page covers the last two.

The two scopes

Project is the default, and it only applies inside a git repository. Outside one, a plain flag line refuses, exit 2, because the rule this product follows is that the git is the manifest: nothing else on a machine can audit what a silent write left behind. Global, with --global or -g, writes under the home directory instead, and needs no git at all.

The two scopes are not the same operation at a different root. They write differently.

ProjectGlobal
What landsa real copy, alwaysa real copy at the first destination, relative links after it
Needs gityes, and refuses outside oneno
Safety netgit status reveals and undoesnone, which is why --force exists
Occupied destinationoverwritten, because git shows itasks in a terminal; refused with exit 3 off a terminal, under --yes or under --dry-run; --force overwrites without asking

The two scopes, seen from disk

The table above gives the rule; this is what it produces. One skill installed for two runtimes that share the same folder:

# project scope, inside the repository
.claude/skills/panlabs-python-standards/
├── SKILL.md
└── references/...

# machine scope, under the home directory
~/.claude/skills/panlabs-python-standards/ ← real copy, the first destination
~/.agents/skills/panlabs-python-standards -> ../../.claude/skills/panlabs-python-standards

The second destination onward is a relative link, and relative on purpose: a home directory that moves, or that is synced across machines, keeps resolving.

doctor knows the difference and reads it from both sides. A link pointing at nothing is a dangling link; a link that turned into a text file, because someone copied the folder without preserving links, is a link turned into text. Both are findings, and a finding fails.

In project scope, every landing is a real copy, never a symlink. This is deliberate: under core.symlinks=false, a git config value a clone can inherit silently, a committed symlink checks out as an ordinary text file instead of a link, and the equipment would be broken for anyone who cloned it. Copying sidesteps that failure mode entirely.

In global scope, each selection climbs a small ladder: the first destination in the runtime table's own order receives a real copy, and every destination after it becomes a relative symlink pointing at that first copy. Relative, specifically so the link keeps working if $HOME itself moves. On Windows the same role is filled by a junction, which needs no elevated privilege. Where neither can be created, the write silently degrades to a second real copy, prints a warning saying so, and still exits 0.

The universal group

Several runtimes read the exact same directory. In project scope, 19 of the 77, including the synthetic universal key itself, read .agents/skills, which makes it the single largest shared destination. Despite the name it is not a path that reaches every runtime: measured against Claude Code 2.1.223, it does not discover skills there, and Codex does not read .claude/skills either.

In global scope the same group shrinks to 6. cline, dexto, kimi-code-cli, loaf, warp and zed all read ~/.agents/skills, while amp reads ~/.config/agents/skills on its own XDG-derived path, codex reads ~/.codex/skills, and cursor reads ~/.cursor/skills.

The plan always names every destination and who reads it, so a selection landing in a shared folder is shown as one write serving several runtimes, never as a promise of one install per runtime.

The runtime table

77 rows: 76 transcribed from the upstream vercel-labs/skills project's own runtime map, attributed in NOTICE, plus vscode, which has no skill destination in either scope and exists in this table purely so the MCP graft step of the wizard has a name for it.

74 of the 77 have a skills destination in global scope. eve and promptscript do not, so asking for either under --global is a valid line with a negative answer, exit 3, rather than an invalid one.

vscode is the third, and it refuses on a different axis: it has no skills destination in either scope, and the refusal does not change with --global. The message is different too, and names what it takes instead:

`vscode` takes MCP servers and has no skills destination of its own;

--runtime vscode --mcp <name> installs; --runtime vscode --skill <name> exits 3 in both scopes.

Global paths below use ~ for the home directory. Several are actually resolved through an environment variable first, falling back to the path shown only when that variable is unset. There are three mechanisms, and the table does not tell them apart:

  • six honour a variable of the tool's own: autohand-code (AUTOHAND_HOME), claude-code (CLAUDE_CONFIG_DIR), codex (CODEX_HOME), grok (GROK_HOME), hermes-agent (HERMES_HOME) and mistral-vibe (VIBE_HOME);
  • six resolve through XDG_CONFIG_HOME before falling back to ~/.config, and they are amp, devin, goose, opencode, replit and universal;
  • one uses the first directory that exists: openclaw looks for ~/.openclaw, ~/.clawdbot and ~/.moltbot in that order, and falls back to the first when none exists.

The other ~/.config paths in the table are literals, not XDG: crush and kimchi live there by direct spelling, and do not move with the variable.

A blank value counts as unset. A relative value is ignored on purpose, and the tool declares that divergence against upstream.

--runtime keyRuntimeProject scopeGlobal scope
aider-deskAiderDesk.aider-desk/skills~/.aider-desk/skills
ampAmp.agents/skills~/.config/agents/skills
antigravityAntigravity.agents/skills~/.gemini/antigravity/skills
antigravity-cliAntigravity CLI.agents/skills~/.gemini/antigravity-cli/skills
astrbotAstrBotdata/skills~/.astrbot/data/skills
autohand-codeAutohand Code CLI.autohand/skills~/.autohand/skills
augmentAugment.augment/skills~/.augment/skills
bobIBM Bob.bob/skills~/.bob/skills
claude-codeClaude Code.claude/skills~/.claude/skills
openclawOpenClawskills~/.openclaw/skills
clineCline.agents/skills~/.agents/skills
codearts-agentCodeArts Agent.codeartsdoer/skills~/.codeartsdoer/skills
codebuddyCodeBuddy.codebuddy/skills~/.codebuddy/skills
codemakerCodemaker.codemaker/skills~/.codemaker/skills
codestudioCode Studio.codestudio/skills~/.codestudio/skills
codexCodex.agents/skills~/.codex/skills
command-codeCommand Code.commandcode/skills~/.commandcode/skills
continueContinue.continue/skills~/.continue/skills
cortexCortex Code.cortex/skills~/.snowflake/cortex/skills
crushCrush.crush/skills~/.config/crush/skills
cursorCursor.agents/skills~/.cursor/skills
deepagentsDeep Agents.agents/skills~/.deepagents/agent/skills
devinDevin for Terminal.devin/skills~/.config/devin/skills
dextoDexto.agents/skills~/.agents/skills
droidDroid.factory/skills~/.factory/skills
eveEveagent/skillsnone
firebenderFirebender.agents/skills~/.firebender/skills
forgecodeForgeCode.forge/skills~/.forge/skills
gemini-cliGemini CLI.agents/skills~/.gemini/skills
github-copilotGitHub Copilot.agents/skills~/.copilot/skills
gooseGoose.goose/skills~/.config/goose/skills
grokGrok Build.grok/skills~/.grok/skills
hermes-agentHermes Agent.hermes/skills~/.hermes/skills
inference-shinference.sh.inferencesh/skills~/.inferencesh/skills
jazzJazz.jazz/skills~/.jazz/skills
junieJunie.junie/skills~/.junie/skills
iflow-cliiFlow CLI.iflow/skills~/.iflow/skills
kiloKilo Code.kilocode/skills~/.kilocode/skills
kimchiKimchi.kimchi/skills~/.config/kimchi/harness/skills
kimi-code-cliKimi Code CLI.agents/skills~/.agents/skills
kiro-cliKiro CLI.kiro/skills~/.kiro/skills
kodeKode.kode/skills~/.kode/skills
lingmaLingma.lingma/skills~/.lingma/skills
loafLoaf.agents/skills~/.agents/skills
mcpjamMCPJam.mcpjam/skills~/.mcpjam/skills
minimax-codeMiniMax Code.minimax/skills~/.minimax/skills
mistral-vibeMistral Vibe.vibe/skills~/.vibe/skills
moxbyMoxby.moxby/skills~/.moxby/skills
muxMux.mux/skills~/.mux/skills
opencodeOpenCode.agents/skills~/.config/opencode/skills
openhandsOpenHands.openhands/skills~/.openhands/skills
onaOna.ona/skills~/.ona/skills
piPi.pi/skills~/.pi/agent/skills
qoderQoder.qoder/skills~/.qoder/skills
qoder-cnQoder CN.qoder/skills~/.qoder-cn/skills
qwen-codeQwen Code.qwen/skills~/.qwen/skills
replitReplit.agents/skills~/.config/agents/skills
reasonixReasonix.reasonix/skills~/.reasonix/skills
rovodevRovo Dev.rovodev/skills~/.rovodev/skills
rooRoo Code.roo/skills~/.roo/skills
tabnine-cliTabnine CLI.tabnine/agent/skills~/.tabnine/agent/skills
terramindTerramind.terramind/skills~/.terramind/skills
tinycloudTinycloud.tinycloud/skills~/.tinycloud/skills
traeTrae.trae/skills~/.trae/skills
trae-cnTrae CN.trae/skills~/.trae-cn/skills
warpWarp.agents/skills~/.agents/skills
windsurfWindsurf.windsurf/skills~/.codeium/windsurf/skills
zedZed.agents/skills~/.agents/skills
zcodeZCode.zcode/skills~/.zcode/skills
zencoderZencoder.zencoder/skills~/.zencoder/skills
zenflowZenflow.zencoder/skills~/.zencoder/skills
neovateNeovate.neovate/skills~/.neovate/skills
pochiPochi.pochi/skills~/.pochi/skills
promptscriptPromptScript.agents/skillsnone
adalAdaL.adal/skills~/.adal/skills
vscodeVS Codenonenone
universalUniversal.agents/skills~/.config/agents/skills

vscode has no row in either column because it is not a skill destination at all. It exists in the table only for the MCP graft, which reads and writes .vscode/mcp.json and nothing under skills/. universal is not a real tool: it is a synthetic key naming the shared .agents/skills destination directly, for when you want to equip that folder without naming every runtime that happens to read it.