Manage all your AI agent spells (commands, skills, agents) in one place and sync them to every tool via symlinks — write once, use everywhere.
- Single source of truth — maintain one spell directory instead of scattered configs
- Symlink-based sync — changes in your source directory are instantly reflected in all tools
- Automatic backup — existing directories are safely backed up before being replaced by symlinks
- Cross-tool agents — one canonical agent
.mdis adapted per tool:.mdsymlink (Claude Code / Cursor), generated.toml(Codex), generated.json(Kiro) - Supported tools:
- Claude Code, Agents, Codex, Cursor, and Kiro — sync global
skills
- Claude Code, Agents, Codex, Cursor, and Kiro — sync global
git clone https://github.com/samwangdd/sync-spells.git
cd sync-spells
npm install
npm run build
npm linkThis registers the global spells command.
spells setupInteractive prompt to specify your spell source directory and choose which tools to enable. Configuration is saved to ~/.sync-spells/config.json.
spells syncCreates symlinks from your source directory into each tool's config directory. Existing real directories are backed up to ~/.sync-spells/backups/.
spells sync also runs an agents pass. Agent definitions are authored once as canonical Markdown in agents/{global,coding,system}/*.md (YAML frontmatter + body) and adapted to each enabled tool:
| Tool | Target | How |
|---|---|---|
| Claude Code | ~/.claude/agents/<name>.md |
symlink (passthrough) |
| Cursor | ~/.cursor/agents/<name>.md |
symlink (passthrough) |
| Codex | ~/.codex/agents/<name>.toml |
generated from frontmatter + body |
| Kiro | ~/.kiro/agents/<name>.json |
generated from frontmatter + body |
Generated files are derived output — edit the canonical .md, never the .toml/.json. Pre-existing real files are backed up before being replaced.
spells push [path]Copies spell files from the specified directory (defaults to current directory) into your source directory. Existing files are skipped.
spells statusShows the active preset and linked skills for the current project. Use spells status --verbose to inspect global tool mapping symlinks.
SyncSpells has five daily concepts:
- Library - all available skills in
skill-category/. - Global profile - the minimal always-available set in
profiles/global.json. - Preset - a working mode that selects skills, such as
codingorlifeos. - Binding - a directory tree mapped to a default preset.
- Project - the current repository using one preset.
Profiles still exist as the backward-compatible storage format for presets.
spells skill list [--category]- List Library skillsspells skill add <path>- Add skill to the Libraryspells skill new <name>- Create a new skillprofiles/global.json- Add a skill to the minimal global profile with an explicitextrasentryspells skill localize <skill> --to <category>- Move a global skill back toknowledge,coding,workflow, orinboxspells bind [list|add|remove]- Manage directory-tree defaults for presetsspells preset [list|show]- Manage presetsspells use [preset]- Activate a preset in the current projectspells resolve [preset]- Inspect the project skill list a preset resolves tospells migrate [--dry-run]- Convert an existing registry to the category layoutspells profiles [list|show]- Backward-compatible profile commandsspells doctor- Health checkspells workspace [init|doctor|migrate]- Manage the workspace manifest and validate skill/agent symlink healthspells config [get|set]- Configuration management
MCP configuration is managed separately from skills. Put shared MCP servers in mcp-registry/global.json and project presets in mcp-registry/presets/<preset>.json.
spells mcp status
spells mcp sync --global --dry-run
spells mcp sync --global
spells mcp use coding --dry-run
spells mcp use codingGlobal MCP sync merges only sync-spells-owned server entries into Claude Code, Cursor, and Codex target files. Existing user-owned settings are preserved and same-name conflicts are refused unless explicitly adopted.
The iCloud sync-spells/ directory is a managed workspace. A workspace.json manifest at its root declares the directories the CLI owns:
{ "version": 1, "library": "skill-category", "profiles": "profiles", "agents": "agents", "legacy": [] }spells workspace init # Write workspace.json (idempotent)
spells workspace doctor # Validate manifest dirs + tool symlink health
spells workspace migrate # Create any missing manifest-declared directoriesworkspace doctor reports a problem when a manifest directory is missing, when a tool's skill-mapping symlink is broken or points at the wrong target, or when a Claude Code / Cursor agent passthrough symlink is dangling — surfacing sync drift before it bites. Run spells sync to repair.
-
Review available skills:
spells skill list
-
Review presets:
spells preset list
-
Activate a preset in a project:
cd /path/to/project spells use -
Check status:
spells status
Use globalize when a skill should be shared by both LiveOS and Coding presets:
spells skill globalize <skill>Use profiles/global.json for skills that should be available in the smallest fallback profile. Add entries one by one under extras; do not import an entire category into the global profile.
Use localize when a global skill should move back into a scoped category:
spells skill localize <skill> --to knowledge
spells skill localize <skill> --to coding
spells skill localize <skill> --to workflow
spells skill localize <skill> --to inboxspells use [preset] resolves the explicit preset or the current directory's longest matching binding, then links project skills directly from the skill category into .codex/skills and .claude/skills. Inbox skills are intentionally excluded from project-level links.
Launch a local web UI to browse all skills, inspect each profile's resolved skill set, and edit a profile recipe (categories / extras / excludes) with a live resolve preview before writing back to JSON.
npm run web:build # one-time / after frontend changes
spells web # http://localhost:4178, opens browser
spells web --port 5000 # custom port (auto-increments if busy)
spells web --no-open # do not open the browsernpm run dev # Run via ts-node (no build needed)
npm run build # Compile TypeScript → dist/
npm test # Run all testsRun a single test file:
npx jest __tests__/lib/symlink.test.tsMIT