@light-merlin-dark/skill-sync
v0.3.6
Published
Sync local repo-backed agent skills across Codex, Claude Code, Cursor, Gemini, Hermes, and other harnesses.
Maintainers
Readme
███████╗██╗ ██╗██╗██╗ ██╗ ███████╗██╗ ██╗███╗ ██╗ ██████╗
██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝╚██╗ ██╔╝████╗ ██║██╔════╝
███████╗█████╔╝ ██║██║ ██║ ███████╗ ╚████╔╝ ██╔██╗ ██║██║
╚════██║██╔═██╗ ██║██║ ██║ ╚════██║ ╚██╔╝ ██║╚██╗██║██║
███████║██║ ██╗██║███████╗███████╗ ███████║ ██║ ██║ ╚████║╚██████╗
╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝
Sync local repo-backed agent skills across Codex, Claude Code, Cursor, Gemini, Hermes, and more.skill-sync keeps local SKILL.md sources installed into agent harnesses using harness-native managed layouts, with drift checks, source-topology diagnostics, conflict detection, and restoreable backups. Most harnesses use thin wrapper directories with a canonical SKILL.md symlink; Codex now uses a materialized skill-directory install for Codex-local skills, and shared Codex-visible skills are routed through materialized ~/.agents/skills bridge entries to avoid duplicate listings in the IDE.
Why This Exists
npx skills is excellent for public and package-based skill workflows.
skill-sync solves a different problem:
- Your skills live in local source repos, not
node_modules - You want one source of truth per skill repo
- You use multiple harnesses with different skill roots
- You want safe sync, dry runs, machine-readable output, and backups before anything gets clobbered
What It Does
- Scans one or more projects roots such as
~/_dev - Discovers:
- top-level
SKILL.md - nested
skills/*/SKILL.md - one-level nested child repos that contain
SKILL.mdorskills/(for example_dev/db/db-cli,_dev/services/ai-guard)
- top-level
- Detects installed harness skill roots
- Supports scoped installs for harness-local skills
- Plans drift without changing anything
- Syncs managed installs into harnesses using harness-native layouts (
<skill>/SKILL.mdwrapper symlinks for most harnesses, materialized directories for Codex-local installs, plus materializedagentsbridge installs for shared Codex-visible skills) - Warns when the same skill slug appears multiple times in your configured project roots
- Collapses harness wrapper mirrors back to canonical sources so duplicate/fanout diagnostics stay focused on real source collisions
- Flags malformed or missing skill frontmatter before Codex or another harness silently skips indexing a skill, and blocks sync when YAML is invalid
- Flags recursive harness traversal hazards that tools like OpenCode will try to parse, including nested descendant
SKILL.mdfiles and missing root skill files - Flags broken root-level harness symlinks that cause Codex/OpenCode parser errors and scan truncation
- Refuses to overwrite unmanaged conflicts silently
- Creates harness
skillsbackups and restores them later
Quick Start
Install globally:
npm install -g @light-merlin-dark/skill-syncInitialize config:
skill-sync config initInspect detected harnesses:
skill-sync harnessesInspect discovered skill sources:
skill-sync sourcesCheck drift:
skill-sync doctor
skill-sync doctor --verbose
skill-sync stabilize
skill-sync codex-auditExecute:
skill-sync execute
skill-sync sync
# Apply safe changes even if some entries conflict (still exits non-zero)
skill-sync execute --continue-on-conflictShortcut:
ss
ss doctor
ss executeDefault Model
By default skill-sync uses:
- config and state home:
~/.skill-sync - default projects root:
~/_dev - managed installs default to wrapper directories; Codex-local installs use materialized directories, and shared Codex-visible skills are routed through materialized
agentsentries whenever Codex compatibility is requested
It complements npx skills; it does not replace it.
Commands
Core:
skill-sync doctor
skill-sync check
skill-sync stabilize
skill-sync codex-audit
skill-sync execute
skill-sync sync
skill-sync repair-sources
skill-sync cache-bust
skill-sync sources
skill-sync harnessesBackups:
skill-sync backup create
skill-sync backup list
skill-sync backup restore <backup-id>Config:
skill-sync config init
skill-sync roots list
skill-sync roots add /path/to/projects
skill-sync roots remove /path/to/projects
skill-sync harness list
skill-sync harness add my-tool ~/.my-tool/skills
skill-sync harness remove my-toolAgent-friendly options:
skill-sync doctor --json
skill-sync execute --dry-run --json
skill-sync stabilize --json
skill-sync stabilize --execute --harness codex --fix-codex-config
skill-sync codex-audit --json
skill-sync codex-audit --fix-config
skill-sync codex-audit --strict-runtime --runtime-max-age-hours 2
skill-sync repair-sources --dry-run --json
skill-sync cache-bust --harness codex --dry-run --json
skill-sync backup restore <id> --dry-run
skill-sync doctor --projects-root /path/to/projects --harness codex
skill-sync doctor --home /tmp/fake-homeBare skill-sync / ss prints a high-signal landing/help view. Human output defaults to a concise summary. Use --verbose when you want the full per-entry plan, including orphan install details during doctor.
Supported Harness Model
Built-in harness roots currently include:
| Harness | Global skills root |
| --- | --- |
| Codex | ~/.codex/skills |
| Agents / Cline / Warp | ~/.agents/skills |
| Claude Code | ~/.claude/skills |
| Cursor | ~/.cursor/skills |
| GitHub Copilot | ~/.copilot/skills |
| Gemini CLI | ~/.gemini/skills |
| Antigravity | ~/.gemini/antigravity/skills |
| Droid / Factory | ~/.factory/skills |
| Hermes | ~/.hermes/skills |
| KiloCode | ~/.kilocode/skills |
| OpenCode | ~/.config/opencode/skills |
| Plain skills root | ~/.skills |
You can add more:
skill-sync harness add codex-beta ~/.codex-beta/skillsSafety Rules
doctornever mutatesexecute/syncreplace managed or missing entries, and prune top-level harness symlinks that point to directoriescleanscans selected harness roots directly (not only state-tracked entries) and removes top-level directory symlinks that pollute parsers- unmanaged conflicts are reported, not overwritten
- duplicate
_devslugs are surfaced before harness-level sync planning - malformed skill metadata is surfaced during
doctor, including missing YAML frontmatter or missingname: - invalid YAML frontmatter is a blocking source error (exit code
3) soexecutecannot report healthy while Codex/OpenCode parsing would still fail - broken nested
skills/<slug>/SKILL.mdsymlinks are surfaced as source errors so sync does not silently drop missing skills - shared harness roots such as
~/.agents/skillsand~/.skillscan still promote fallback sources when no project-root source exists for the same slug - vendor harness roots such as Codex, Hermes, Claude Code, Cursor, OpenCode, KiloCode, and similar tool-local folders default to local-only installs unless frontmatter explicitly widens the scope
- harness-native skills can stay local-only via frontmatter instead of being fanned out everywhere
- recursive harness-root pollution is surfaced during
doctorbefore OpenCode or another recursive scanner hits duplicate or unreadable descendant skill files - broken root-level harness symlinks are surfaced during
doctorand pruned automatically duringexecute - cross-harness top-level symlinks (for example
.agents/skills/foo -> ~/.codex/skills/foo) are surfaced as traversal hazards so fanout-induced missing/duplicate installs are visible - high source fanout for the same slug is surfaced as a warning so mirrored
_devcopies can be reduced before index/caching drift appears - codex-specific drift is auditable via
codex-audit: invalidskills.configblocks, stale paths, legacy alias paths, runtime visibility gaps where a managed skill is installed on disk but missing from the active Codex session skill list, and workspace visibility gaps where Codex's liveskills/listomits installed managed skills from Plugins > Skills - stale Codex runtime snapshots are reported as
uncertaingaps by default, andcodex-auditnow separately flags snapshot/install drift when missing skills were installed after the thread snapshot (this is treated as a failure so stale thread skill seeds are not misreported as healthy) - Codex runtime snapshot selection is timestamp-aware (parsed snapshot capture time, not file mtime), and thread matching is rollout-id based, so cache-bust file touches or cross-thread content do not skew audit results
- Codex workspace visibility checks can now distinguish install-health from root-recognition failures by probing the live app-server and verifying whether missing skills reappear only when extra user roots are supplied
- backups snapshot harness
skillsdirectories before or after risky changes - restore can recreate symlinks when the original source still exists
- restore falls back to minimal backed-up
SKILL.mdcontent when the source no longer exists
End-to-end stabilization (safe dry-run by default):
skill-sync stabilize
skill-sync stabilize --execute
skill-sync stabilize --execute --harness codex --fix-codex-configCodex visibility/config audit and repair (including live-session and workspace Plugins > Skills visibility gaps):
skill-sync codex-audit
skill-sync codex-audit --cwd /Users/merlin/_dev/skill-sync
skill-sync codex-audit --fix-config
skill-sync codex-audit --strict-runtime --runtime-max-age-hours 2If you need to skip the live Codex app-server workspace probe in a controlled environment or test harness:
SKILL_SYNC_SKIP_CODEX_APP_SERVER=1 skill-sync codex-auditRepair broken nested source files (for example skills/<slug>/SKILL.md -> ../../SKILL.md with missing root files):
skill-sync repair-sources --dry-run
skill-sync repair-sourcesForce a harness reload signal (touches installed SKILL.md files and, for Codex, config/state/session cache files including the active thread session when CODEX_THREAD_ID is available):
skill-sync cache-bust --harness codex --dry-run
skill-sync cache-bust --harness codexBackup and Restore
Create a backup:
skill-sync backup createList backups:
skill-sync backup listRestore one:
skill-sync backup restore 2026-03-25T13-45-00-000ZDry run a restore:
skill-sync backup restore 2026-03-25T13-45-00-000Z --dry-runBackups live under:
~/.skill-sync/backups/Each backup includes:
- a manifest of harness roots and entries
- original symlink targets when present
- backed-up
SKILL.mdsnapshots for restore fallback - a state snapshot for managed entries
JSON Output
skill-sync is designed for agents first.
Example:
skill-sync doctor --jsonReturns structured data for:
- discovered sources
- source warnings and source errors
- selected harness roots
- planned actions
- conflicts
- changes and ok counts
How Source Discovery Works
For every immediate child repo under each configured projects root, skill-sync looks for:
<repo>/SKILL.md<repo>/skills/*/SKILL.md
It also inspects detected harness roots. Project-root sources win over harness-installed sources when the same slug exists in both places. Wrapper installs discovered under harness roots are resolved back to their canonical source files, and non-owning harness mirrors are ignored as discovery sources.
Harness-root sources can also declare install scope in frontmatter:
skill-sync-scope: local-onlykeeps that source on its owning harness only- vendor harness roots default to this behavior even without explicit frontmatter
- shared roots like
agentsandskillsstay global by default skill-sync-install-on: [codex, hermes]limits installs to specific harness idsskill-sync-scope: globalexplicitly widens a harness-root source back out to other harnesses
Canonical install names default to:
slugify(frontmatter name)whenname:exists- otherwise a folder-derived fallback
You can override install names per source and per harness in ~/.skill-sync/config.json.
You can also exclude or prefer project paths during discovery:
{
"discovery": {
"ignorePathPrefixes": [
"/Users/you/_dev/some-upstream-clone"
],
"preferPathPrefixes": [
"/Users/you/_dev/packages/stack"
]
}
}Local Development
Install dependencies:
bun installRun the CLI directly:
bun run src/index.ts doctorRun tests:
bun test tests/unit tests/integrationBuild:
bun run buildRelease
Patch release:
make releaseThis bumps the patch version, moves the ## Unreleased notes into the new versioned changelog section, runs lint/test/build, publishes to npm, commits the release, pushes main, tags the release, and creates or updates the GitHub release.
Positioning
Use npx skills when:
- you are installing public or package-provided skills
- your source of truth is a GitHub repo or package ecosystem workflow
Use skill-sync when:
- your source of truth is local repos on disk
- you want canonical wrapper installs into multiple harnesses without top-level directory symlink pollution
- you need backup and restore around those installs
License
MIT
Built by Robert E. Beckner III (Merlin)
