Simple, easy to use and brings order to AI agent chaos.
One folder. All your tools. Zero repetition.
For AI Assistants: Read INSTALL-SKILL.md for installation instructions.
You use Claude Code. And Cursor. Maybe Windsurf. Each one has its own skills folder, its own config, its own path. You build a great review-pr skill — and now you maintain it in three places.
Your teammate clones the repo. Nothing works.
.easyskillz/skills/ ← one folder, committed to git
review-pr/
SKILL.md
commit-msg/
SKILL.md
Run easyskillz sync once. Every tool gets a symlink. Every teammate who clones runs easyskillz sync and everything is wired in seconds.
Latest stable:
npm install -g easyskillzAlpha (v2.0.0 - domain-based commands, OOP architecture):
npm install -g easyskillz@alphav2.0.0-alpha.3: Commands now use domain-based structure:
easyskillz <domain> <action>
easyskillz skill add <name> # create a skill and wire it to all tools
easyskillz skill list # show all skills (active + deactivated)
easyskillz skill deactivate <name> # soft delete (reversible)
easyskillz skill activate <name> # restore a deactivated skill
easyskillz skill remove <name> # permanently delete (requires --confirm for AI)easyskillz tool register <name> # add a tool and wire all skills to it
easyskillz tool unregister <name> # remove a tool (requires --mode and --confirm for AI)
easyskillz tool list # show registered toolseasyskillz project sync # detect tools, wire everything, set up .easyskillz/
easyskillz project doctor # report stale targets and metadata issues
easyskillz project export --target <path> # copy skills + config to another projecteasyskillz docs sync # update instruction files for all tracked folders
easyskillz docs list # show instruction files and their status# All flags in one command - no interactive prompts
easyskillz project sync --docs=yes --docs-strategy=unified --gitignore=full
easyskillz skill remove my-skill --confirm
easyskillz tool unregister cursor --mode=full --confirm$ easyskillz project sync
Scanning for AI tools...
✓ Claude Code (.claude/skills)
✓ Cursor (.cursor/rules)
✗ Codex (not found)
Reading config (.easyskillz/easyskillz.json)...
Registered: claude, cursor
Strategy: symlink
Testing symlink support...
✓ symlinks work
Scanning for unwired skills...
review-pr → Claude Code: ✗ missing
review-pr → Cursor: ✗ missing
commit-msg → Claude Code: ✗ missing
Plan:
[ wire ] .claude/skills/review-pr → .easyskillz/skills/review-pr
[ wire ] .cursor/rules/review-pr.mdc → .easyskillz/skills/review-pr
[ wire ] .claude/skills/commit-msg → .easyskillz/skills/commit-msg
Proceed? [Y/n]
✓ Wired review-pr → Claude Code
✓ Wired review-pr → Cursor
✓ Wired commit-msg → Claude Code
Done. 2 tool(s) wired via symlink.
You see exactly what will happen before it happens. One confirmation. Done.
easyskillz is designed to minimize git surface area and eliminate developer friction in large teams.
What gets committed — and what doesn't:
| Path | Committed | Why |
|---|---|---|
.easyskillz/skills/ |
✓ yes | shared source of truth for all skills |
.easyskillz/easyskillz.json |
✓ yes | shared tool list so teammates wire the same tools |
.claude/skills/, .cursor/rules/, .agents/skills/, etc. |
✗ no | generated tool output, regenerated on sync |
CLAUDE.md, AGENTS.md, .cursor/rules, etc. |
✗ no | personal tool config, differs per developer |
Each developer uses whichever AI tools they prefer. Their local config, symlinks, and instruction files never touch git. Only the skills themselves — the shared knowledge — are committed.
# Day 1 — you set it up
easyskillz sync
easyskillz add review-pr
easyskillz add commit-msg
git add .easyskillz/skills/
git commit -m "add shared skills"
git push# Teammate clones — uses Cursor, you use Claude, no conflict
git clone <repo>
easyskillz sync ← detects their tools, wires all skills automatically
✓ Done. 2 tool(s) wired via symlink.No merge conflicts on tool config. No PRs blocked because someone uses a different editor. The skill content is the only thing that matters — and that's exactly what gets shared.
easyskillz is designed to "just work." It handles several complex AI tool behaviors automatically:
- Native Agent Targets: Codex uses
.agents/skills/, Gemini uses.gemini/skills/, Cursor uses.cursor/rules/*.mdc, Claude and Copilot use native skill folders, and Windsurf uses both.windsurf/skills/and.windsurf/workflows/*.md. - Windsurf Dual Output: registering or syncing Windsurf generates a skill folder and a workflow file for every skill.
- Skill Auto-Repair: easyskillz ensures every
SKILL.mdhas anameand usefuldescriptionso agents can discover and activate it. - Project Doctor:
easyskillz project doctorreports stale.codex/skills, stale.cursor/skills, pointer-only instruction files, missing generated targets, and weak metadata. - Surgical Gitignore: When using the
smartstrategy (recommended), easyskillz surgically ignores only the files it manages (like symlinks and settings). Your custom tool files (hooks, scripts, logs) stay tracked by git. - Robust Detection: Tools are detected via multiple markers — whether it's a config file, an instruction file, or just the root folder, easyskillz will find it.
- Normalization: Tool IDs are case-insensitive.
easyskillz tool register CurSorworks exactly likecursor.
| Tool | Generated Target | Instruction File |
|---|---|---|
| Claude Code | .claude/skills/ |
CLAUDE.md |
| Codex | .agents/skills/ |
AGENTS.md |
| Cursor | .cursor/rules/*.mdc |
AGENTS.md |
| Windsurf | .windsurf/skills/ plus .windsurf/workflows/*.md |
AGENTS.md |
| GitHub Copilot | .github/skills/ |
.github/copilot-instructions.md |
| Gemini CLI | .gemini/skills/ |
GEMINI.md |
easyskillz probes symlink support on your machine automatically.
SYMLINKS AVAILABLE ████████████████ → uses symlinks (always in sync)
SYMLINKS UNAVAILABLE ████████████████ → copies real generated files
Symlink - a .claude/skills/review-pr directory that IS .easyskillz/skills/review-pr. Edit once, all tools see it instantly.
Copy fallback - a real generated skill directory or rule file. No pointer stubs.
Workflow (Windsurf) - a flat .windsurf/workflows/review-pr.md file generated alongside the skill directory for every Windsurf skill.
No silent failures. No copies getting out of sync.
Manage your project's .gitignore block automatically:
- smart (recommended) — Surgical ignore. Only ignores managed skills/configs, keeps your custom files tracked.
- full — Blanket ignore root tool folders. Cleanest repo, but may hide custom files in tool dirs.
- minimal — Only ignore files that might cause merge conflicts.
- none — Manual management.
easyskillz uses a managed block (# easyskillz-start ... # easyskillz-end) so it can update its rules as you add more tools.
.easyskillz/easyskillz.json is committed to git. It's how teammates know what to wire.
{
"tools": ["claude", "cursor"],
"linkStrategy": "symlink",
"manageDocs": true,
"docsStrategy": "unified"
}Instruction file management (optional):
manageDocs: true— easyskillz centralizes instruction files in.easyskillz/docs/and leaves real content at native instruction pathsdocsStrategy: "unified"— oneINSTRUCTION.mdper folder for all toolsdocsStrategy: "tool-specific"— separate file per tool per folder
Symlinks themselves are gitignored — they're machine-local. Centralized docs in .easyskillz/docs/ are committed.
All commands support --json for machine-readable output:
$ easyskillz sync --json
{"ok":true,"tools":["claude","cursor"],"strategy":"symlink","actions":["wire","wire","instruct"]}- No interactive prompts when stdin is not a TTY
- Exit code
0on success, non-zero on failure - Errors to stderr, output to stdout
- Safe to re-run — fully idempotent
sync creates a _easyskillz meta-skill that teaches AI agents how to use easyskillz.
Optional: Enable instruction file management during first sync:
- Automatically scans entire repo for
CLAUDE.md,AGENTS.md, etc. - Centralizes them in
.easyskillz/docs/ - Replaces with symlinks when possible, otherwise copies real content
- Choose
unified(one source for all tools) ortool-specific(separate per tool) - Fully automated after initial choice
Your AI agents will use the CLI to create skills and manage instruction files. The loop closes.
Adding a new tool is a one-PR contribution:
- Add an entry to
src/registry.js - Add a detector file to
src/detectors/
See CONTRIBUTING.md for the full template.
Branching
- Branch from
main - Name:
feat/<tool-name>,fix/<description>,docs/<description>
Pull Requests
- One PR = one change. Adding a tool = one detector file + one registry entry, nothing more
- PR title describes the change, not the task:
Add Cline detectornotWorking on new tool support - All PRs require a passing smoke test:
node bin/easyskillz.js syncin a temp project with your tool present
Commits
- Conventional commits:
feat:,fix:,docs:,chore: - One logical change per commit
Code Style
- Plain CommonJS, zero runtime dependencies — keep it that way
- Every operation must be idempotent
- Every action must be visible to the user before it happens (glass box)
- If it touches the filesystem, it needs an existence check first
What We Won't Merge
- Runtime dependencies (
chalk,commander,inquirer, etc.) - Non-idempotent operations
- Silent side effects
- More than 3 questions to the user in any command
You could. But then:
- No shared config for teammates
- No auto-detection of tools
- No idempotent re-wire on clone
- No instruction file updates
- No generated copy fallback for restricted environments
- No
easyskillz addto wire new skills everywhere at once
easyskillz is the missing glue.
easyskillz remove <name>— unwire and delete a skill from all toolseasyskillz list— show all skills and their wiring status per tooleasyskillz project doctor- quick health check, flags stale targets, pointer stubs, and missing outputs- Skill templates —
easyskillz add <name> --template <type>for common patterns
MIT License · Contributing · Development · Issues