{"id":47673398,"url":"https://github.com/light-merlin-dark/skill-sync","last_synced_at":"2026-04-07T03:01:16.169Z","repository":{"id":346809663,"uuid":"1191690557","full_name":"light-merlin-dark/skill-sync","owner":"light-merlin-dark","description":"Sync local repo-backed agent skills across Codex, Claude Code, Cursor, Gemini, Hermes, and more. Safe symlink sync, drift checks, backups, and restore.","archived":false,"fork":false,"pushed_at":"2026-03-26T23:25:02.000Z","size":68,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T01:15:59.108Z","etag":null,"topics":["agent-skills","ai-agents","automation","backup","claude-code","cli","codex","cursor","developer-tools","gemini","github-copilot","hermes","restore","symlink"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/light-merlin-dark.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-25T13:47:29.000Z","updated_at":"2026-03-26T23:25:01.000Z","dependencies_parsed_at":"2026-03-26T17:03:43.233Z","dependency_job_id":null,"html_url":"https://github.com/light-merlin-dark/skill-sync","commit_stats":null,"previous_names":["light-merlin-dark/skill-sync"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/light-merlin-dark/skill-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/light-merlin-dark%2Fskill-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/light-merlin-dark%2Fskill-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/light-merlin-dark%2Fskill-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/light-merlin-dark%2Fskill-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/light-merlin-dark","download_url":"https://codeload.github.com/light-merlin-dark/skill-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/light-merlin-dark%2Fskill-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31498070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"online","status_checked_at":"2026-04-07T02:00:07.164Z","response_time":105,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skills","ai-agents","automation","backup","claude-code","cli","codex","cursor","developer-tools","gemini","github-copilot","hermes","restore","symlink"],"created_at":"2026-04-02T13:08:09.921Z","updated_at":"2026-04-07T03:01:16.164Z","avatar_url":"https://github.com/light-merlin-dark.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\n███████╗██╗  ██╗██╗██╗     ██╗         ███████╗██╗   ██╗███╗   ██╗ ██████╗\n██╔════╝██║ ██╔╝██║██║     ██║         ██╔════╝╚██╗ ██╔╝████╗  ██║██╔════╝\n███████╗█████╔╝ ██║██║     ██║         ███████╗ ╚████╔╝ ██╔██╗ ██║██║     \n╚════██║██╔═██╗ ██║██║     ██║         ╚════██║  ╚██╔╝  ██║╚██╗██║██║     \n███████║██║  ██╗██║███████╗███████╗    ███████║   ██║   ██║ ╚████║╚██████╗\n╚══════╝╚═╝  ╚═╝╚═╝╚══════╝╚══════╝    ╚══════╝   ╚═╝   ╚═╝  ╚═══╝ ╚═════╝\n\nSync local repo-backed agent skills across Codex, Claude Code, Cursor, Gemini, Hermes, and more.\n```\n\n`skill-sync` keeps local `SKILL.md` sources installed into agent harnesses as symlinks, with drift checks, source-topology diagnostics, conflict detection, and restoreable backups.\n\n## Why This Exists\n\n`npx skills` is excellent for public and package-based skill workflows.\n\n`skill-sync` solves a different problem:\n\n- Your skills live in local source repos, not `node_modules`\n- You want one source of truth per skill repo\n- You use multiple harnesses with different skill roots\n- You want safe sync, dry runs, machine-readable output, and backups before anything gets clobbered\n\n## What It Does\n\n- Scans one or more projects roots such as `~/_dev`\n- Discovers:\n  - top-level `SKILL.md`\n  - nested `skills/*/SKILL.md`\n- Detects installed harness skill roots\n- Supports scoped installs for harness-local skills\n- Plans drift without changing anything\n- Syncs symlinked installs into harnesses\n- Warns when the same skill slug appears multiple times in your configured project roots\n- Flags malformed or missing skill frontmatter before Codex or another harness silently skips indexing a skill\n- Flags recursive harness traversal hazards that tools like OpenCode will try to parse, including nested descendant `SKILL.md` files and missing root skill files\n- Refuses to overwrite unmanaged conflicts silently\n- Creates harness `skills` backups and restores them later\n\n## Quick Start\n\nInstall globally:\n\n```bash\nnpm install -g @light-merlin-dark/skill-sync\n```\n\nInitialize config:\n\n```bash\nskill-sync config init\n```\n\nInspect detected harnesses:\n\n```bash\nskill-sync harnesses\n```\n\nInspect discovered skill sources:\n\n```bash\nskill-sync sources\n```\n\nCheck drift:\n\n```bash\nskill-sync doctor\nskill-sync doctor --verbose\n```\n\nExecute:\n\n```bash\nskill-sync execute\nskill-sync sync\n# Apply safe changes even if some entries conflict (still exits non-zero)\nskill-sync execute --continue-on-conflict\n```\n\nShortcut:\n\n```bash\nss\nss doctor\nss execute\n```\n\n## Default Model\n\nBy default `skill-sync` uses:\n\n- config and state home: `~/.skill-sync`\n- default projects root: `~/_dev`\n- symlink-first installs\n\nIt complements `npx skills`; it does not replace it.\n\n## Commands\n\nCore:\n\n```bash\nskill-sync doctor\nskill-sync check\nskill-sync execute\nskill-sync sync\nskill-sync sources\nskill-sync harnesses\n```\n\nBackups:\n\n```bash\nskill-sync backup create\nskill-sync backup list\nskill-sync backup restore \u003cbackup-id\u003e\n```\n\nConfig:\n\n```bash\nskill-sync config init\nskill-sync roots list\nskill-sync roots add /path/to/projects\nskill-sync roots remove /path/to/projects\nskill-sync harness list\nskill-sync harness add my-tool ~/.my-tool/skills\nskill-sync harness remove my-tool\n```\n\nAgent-friendly options:\n\n```bash\nskill-sync doctor --json\nskill-sync execute --dry-run --json\nskill-sync backup restore \u003cid\u003e --dry-run\nskill-sync doctor --projects-root /path/to/projects --harness codex\nskill-sync doctor --home /tmp/fake-home\n```\n\nBare `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`.\n\n## Supported Harness Model\n\nBuilt-in harness roots currently include:\n\n| Harness | Global skills root |\n| --- | --- |\n| Codex | `~/.codex/skills` |\n| Agents / Cline / Warp | `~/.agents/skills` |\n| Claude Code | `~/.claude/skills` |\n| Cursor | `~/.cursor/skills` |\n| GitHub Copilot | `~/.copilot/skills` |\n| Gemini CLI | `~/.gemini/skills` |\n| Antigravity | `~/.gemini/antigravity/skills` |\n| Droid / Factory | `~/.factory/skills` |\n| Hermes | `~/.hermes/skills` |\n| KiloCode | `~/.kilocode/skills` |\n| OpenCode | `~/.config/opencode/skills` |\n| Plain skills root | `~/.skills` |\n\nYou can add more:\n\n```bash\nskill-sync harness add codex-beta ~/.codex-beta/skills\n```\n\n## Safety Rules\n\n- `doctor` never mutates\n- `execute` / `sync` only replace entries the tool owns or missing entries\n- unmanaged conflicts are reported, not overwritten\n- duplicate `_dev` slugs are surfaced before harness-level sync planning\n- malformed skill metadata is surfaced during `doctor`, including missing YAML frontmatter or missing `name:`\n- shared harness roots such as `~/.agents/skills` and `~/.skills` can still promote fallback sources when no project-root source exists for the same slug\n- 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\n- harness-native skills can stay local-only via frontmatter instead of being fanned out everywhere\n- recursive harness-root pollution is surfaced during `doctor` before OpenCode or another recursive scanner hits duplicate or unreadable descendant skill files\n- backups snapshot harness `skills` directories before or after risky changes\n- restore can recreate symlinks when the original source still exists\n- restore falls back to minimal backed-up `SKILL.md` content when the source no longer exists\n\n## Backup and Restore\n\nCreate a backup:\n\n```bash\nskill-sync backup create\n```\n\nList backups:\n\n```bash\nskill-sync backup list\n```\n\nRestore one:\n\n```bash\nskill-sync backup restore 2026-03-25T13-45-00-000Z\n```\n\nDry run a restore:\n\n```bash\nskill-sync backup restore 2026-03-25T13-45-00-000Z --dry-run\n```\n\nBackups live under:\n\n```bash\n~/.skill-sync/backups/\n```\n\nEach backup includes:\n\n- a manifest of harness roots and entries\n- original symlink targets when present\n- backed-up `SKILL.md` snapshots for restore fallback\n- a state snapshot for managed entries\n\n## JSON Output\n\n`skill-sync` is designed for agents first.\n\nExample:\n\n```bash\nskill-sync doctor --json\n```\n\nReturns structured data for:\n\n- discovered sources\n- source warnings and source errors\n- selected harness roots\n- planned actions\n- conflicts\n- changes and ok counts\n\n## How Source Discovery Works\n\nFor every immediate child repo under each configured projects root, `skill-sync` looks for:\n\n- `\u003crepo\u003e/SKILL.md`\n- `\u003crepo\u003e/skills/*/SKILL.md`\n\nIt also inspects detected harness roots. Project-root sources win over harness-installed sources when the same slug exists in both places.\n\nHarness-root sources can also declare install scope in frontmatter:\n\n- `skill-sync-scope: local-only` keeps that source on its owning harness only\n- vendor harness roots default to this behavior even without explicit frontmatter\n- shared roots like `agents` and `skills` stay global by default\n- `skill-sync-install-on: [codex, hermes]` limits installs to specific harness ids\n- `skill-sync-scope: global` explicitly widens a harness-root source back out to other harnesses\n\nCanonical install names default to:\n\n- `slugify(frontmatter name)` when `name:` exists\n- otherwise a folder-derived fallback\n\nYou can override install names per source and per harness in `~/.skill-sync/config.json`.\n\nYou can also exclude or prefer project paths during discovery:\n\n```json\n{\n  \"discovery\": {\n    \"ignorePathPrefixes\": [\n      \"/Users/you/_dev/some-upstream-clone\"\n    ],\n    \"preferPathPrefixes\": [\n      \"/Users/you/_dev/packages/stack\"\n    ]\n  }\n}\n```\n\n## Local Development\n\nInstall dependencies:\n\n```bash\nbun install\n```\n\nRun the CLI directly:\n\n```bash\nbun run src/index.ts doctor\n```\n\nRun tests:\n\n```bash\nbun test tests/unit tests/integration\n```\n\nBuild:\n\n```bash\nbun run build\n```\n\n## Release\n\nPatch release:\n\n```bash\nmake release\n```\n\nThis 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.\n\n## Positioning\n\nUse `npx skills` when:\n\n- you are installing public or package-provided skills\n- your source of truth is a GitHub repo or package ecosystem workflow\n\nUse `skill-sync` when:\n\n- your source of truth is local repos on disk\n- you want symlinked installs into multiple harnesses\n- you need backup and restore around those installs\n\n## License\n\nMIT\n\n---\n\nBuilt by [Robert E. Beckner III (Merlin)](https://rbeckner.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flight-merlin-dark%2Fskill-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flight-merlin-dark%2Fskill-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flight-merlin-dark%2Fskill-sync/lists"}