Sync and Share
| Field | Value |
|---|---|
| Type | Skill Resource |
| Source | ~/.copilot/skills/skill-forge/references/sync-and-share.md |
| Description | Not specified |
Source Content
Sync and Share
How to move skills between tools, share them with teams, and keep copies in sync.
The reality
All three tools (Claude Code, Codex, GitHub Copilot) read the same SKILL.md format (name + description frontmatter, plus optional references/, scripts/, assets/). So “conversion” is rarely a rewrite — the real work is doing the copy safely:
- Validate the skill is portable (required frontmatter,
namematches folder, no dead links). - Normalize frontmatter to the target tool’s dialect when asked (
--strict). - Clean-copy the whole folder, excluding
__pycache__/,*.pyc,.DS_Store,.git/, etc.
A plain cp -r skips none of that — it can install a skill under the wrong id and carries build junk into a teammate’s repo. Always go through scripts/skill_sync.py.
Install locations
Each tool keys a skill by its folder name, so each destination gets <base>/<skill-name>/.
| Tool | Global skills directory | Notes |
|---|---|---|
| Claude Code | ~/.claude/skills/<name>/ | May not exist yet; sync creates it. Project skills also load from <repo>/.claude/skills/. |
| Codex | ~/.codex/skills/<name>/ | ~/.codex/skills/.system/ is reserved — never sync into it. |
| Copilot | ~/.copilot/skills/<name>/ | The source of truth; a real git repo. |
| Team / project folder | <path>/<name>/ | Any folder passed with --dir, e.g. a shared documentation repo. |
Frontmatter dialects
Extra keys are harmless — every tool ignores frontmatter it does not recognize — so the default is to preserve every key exactly. Pass --strict only when a destination should not see foreign keys.
name and description are required everywhere and never dropped.
Claude Code
Recognizes name, description, license, allowed-tools, metadata, compatibility. Uses description for triggering; does not read a triggers: list.
Codex
Recognizes name, description, license, metadata. Codex’s own skill-creator uses metadata.short-description for a terse label. Does not read triggers:.
Copilot
Recognizes name, description, license, metadata, and a triggers: list. This is the only dialect that reads triggers:.
Generic (--dir folders)
Defaults to the universal core — name, description, license, metadata. Override with --tool claude|codex|copilot when a --dir copy is destined for a specific tool.
Commands
list
Show every skill in a source tree with the first sentence of its description.
python3 scripts/skill_sync.py list [--source DIR]validate
Check that skill folders are well-formed and portable. Exits non-zero if any errors are found, so it works as a CI gate.
python3 scripts/skill_sync.py validate <skill-dir>... [--target claude|codex|copilot|generic]What it checks:
SKILL.mdpresent with valid---frontmatter.- Required keys
nameanddescriptionpresent. nameis a valid slug (^[a-z0-9][a-z0-9-]*$, ≤ 64) and equals the folder name.descriptionnon-empty (warning if over ~1024 chars).- Relative reference links resolve to existing files.
- Frontmatter keys foreign to the target dialect (warning).
sync
Validate, then clean-copy skills to one or more destinations. A skill that fails validation for any target dialect is skipped with its errors printed — never partially copied.
python3 scripts/skill_sync.py sync <name-or-path>... \ [--all] [--to claude,codex,copilot] [--dir PATH]... \ [--tool DIALECT] [--strict] [--force] [--dry-run] [--source DIR]Selecting skills:
- Positional
<name-or-path>— bare skill name (resolved under--source) or a path to a skill folder. Repeatable. --all— every skill in--source. Usually paired with a single--to.--source DIR— where bare names are resolved. Default:~/.copilot/skills.
Choosing destinations (at least one required):
--to TOOLS— comma-separated tool names:claude,codex,copilot. Each maps to that tool’s global skills directory.--dir PATH— an arbitrary destination folder; the skill lands in<PATH>/<name>/. Repeatable.
Controlling the copy:
--tool DIALECT— frontmatter dialect for--dirtargets. Default:generic.--strict— drop frontmatter keys the target dialect does not recognize.--prompt— also write<name>.prompt.md(a paste-into-ChatGPT prompt) into each--dirshare. Ignored for--totool targets.--force— overwrite an existing destination. Without it, existing destinations are reported asEXISTSand left untouched.--dry-run— print planned actions and would-be-stripped keys; write nothing.
prompt
Flatten a skill into one self-contained message a person can paste into ChatGPT (or any chat LLM) that has no agent, filesystem, or way to run scripts. Every text reference the skill ships is inlined (not just the ones SKILL.md links).
python3 scripts/skill_sync.py prompt <name-or-path> [--source DIR] [--out FILE]remove
Clean up deleted skill copies from destination directories. Run this after merging or deleting a skill from the source tree to propagate the deletion to Claude, Codex, and any team folders.
python3 scripts/skill_sync.py remove <name>... \ [--to claude,codex,copilot] [--dir PATH]... [--dry-run]The remove command:
- Takes skill names (not paths) from the source tree’s
.copilot/skills/registry. - Removes matching folders from each
--totool target and--dirfolders. - Exits 0 on success, 1 if a skill name is invalid or removal fails.
Used in the post-commit hook to propagate deleted skills:
python3 "$SYNC" remove "${gone[@]}" --to claude,codex "${DRYFLAG[@]}"Recipes
Share only certain skills with a team folder
python3 scripts/skill_sync.py sync technical-writing docs-that-teach \ --dir ~/Code/maryland/documentation --strict --promptpython3 scripts/skill_sync.py sync adr \ --dir ~/Code/maryland/documentation --strict --prompt--prompt drops a <name>.prompt.md in each folder for teammates on ChatGPT; drop it if everyone on the team uses an agent.
Install one skill in every tool
python3 scripts/skill_sync.py sync css --to claude,codex,copilot --forceConvert one skill to Codex format and install it
python3 scripts/skill_sync.py sync agile-product-owner --to codex --strict --force--strict drops the Copilot-only triggers: block Codex does not use.
Propagate the whole library to Claude Code
python3 scripts/skill_sync.py sync --all --to claude --dry-run # previewpython3 scripts/skill_sync.py sync --all --to claude --force # do itRemove deleted skills after a consolidation
# After merging skill-creator + skill-sync into skill-forge and deleting the source dirs:python3 scripts/skill_sync.py remove skill-creator skill-sync --to claude,codex --forceJunk that is never copied
Build and editor noise so destinations stay reviewable: Directories: __pycache__, .git, .hg, .svn, .pytest_cache, .mypy_cache, .ruff_cache, .venv, venv, node_modules, .idea, .vscode. Files: *.pyc, *.pyo, *.pyd, .DS_Store, *.swp, *.swo, Thumbs.db, *.egg-info, .coverage.
This is the main reason to never hand-copy: cp -r would install machine-specific cruft into every teammate’s folder.
Workflow
- See what’s available —
python3 scripts/skill_sync.py list. - Dry-run first — add
--dry-runto any sync to see exactly what would be written. - Sync — drop
--dry-run. Add--forceto overwrite existing destinations. - Confirm — the command prints one line per destination.
Rules that keep copies trustworthy
- Validate before writing, always. A skill with a
name/folder mismatch or a dead reference is skipped with an explanation — never partially copied. - Never hand-copy.
cp -rdrags junk and skips validation; route every move through the script. - Preserve by default, strip on purpose. Keep all frontmatter unless the user wants a clean single-tool copy, then use
--strict. - Source of truth is
~/.copilot/skills/. Edit skills there and sync outward; do not edit a downstream copy and sync backward, or the tools will drift.