From dj-music
This skill should be used when the user asks to sync a playlist, push or pull from Yandex Music, search YM, manage YM playlists, or manage YM likes. Covers bidirectional sync, playlist management, search and likes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dj-music:ym-syncThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide the user through syncing local playlists with Yandex Music via the v1 polymorphic dispatchers. See @docs/tool-catalog.md (**20 tools** = 14 core dispatchers + 6 UI Prefab + 27 resources).
Guide the user through syncing local playlists with Yandex Music via the v1 polymorphic dispatchers. See @docs/tool-catalog.md (20 tools = 14 core dispatchers + 6 UI Prefab + 27 resources).
Current state (v1.3.7): DISABLED_NAMESPACE_TAGS in app/server/visibility.py is an empty frozenset — every namespace is visible at startup, including provider:write and sync. Rationale: Claude Code does not always honour notifications/tools/list_changed mid-session, so server-side mcp.disable(tags=...) would hide tools without the client knowing they became unlockable.
unlock_namespace is still useful for:
notifications/tools/list_changedunlock_namespace(namespace="provider:write", action="status") # check status
unlock_namespace(namespace="provider:write", action="unlock") # unlock (no-op for visibility in Claude Code today)
unlock_namespace(namespace="sync", action="unlock")
unlock_namespace(namespace="all", action="unlock") # provider:write + sync + crud:destructive + ui:read
namespace accepts: crud:destructive, provider:write, sync, ui:read, all.
provider_search(provider="yandex", query="...", type="tracks", limit=20) — search tracks (plural tracks, см. @.claude/rules/ym.md)type values: tracks, albums, artists, playlists, allprovider_read)provider_read(provider="yandex", entity="track", id=<ym_track_id>)provider_read(provider="yandex", entity="track_batch", params={"track_ids": ["t1","t2"]}) (legacy ids key still accepted)provider_read(provider="yandex", entity="album", id=<album_id>, params={"include_tracks": true})provider_read(provider="yandex", entity="artist_tracks", id=<artist_id>, params={"page": 0})provider_read(provider="yandex", entity="track_similar", id=<ym_track_id>, params={"limit": 20})provider_read(provider="yandex", entity="playlist", id="<owner>:<kind>") (or pass params={"kind": 1234})provider_read(provider="yandex", entity="playlist_list")provider_read(provider="yandex", entity="likes") / entity="dislikes"provider_write — namespace provider:write, locked)Identify a playlist by kind (numeric). Mutating actions need a fresh revision — re-fetch via provider_read after each edit.
provider_write(provider="yandex", entity="playlist", operation="create", params={"name": "My Set"})provider_write(provider="yandex", entity="playlist", operation="rename", params={"kind": 1234, "name": "New"})provider_write(provider="yandex", entity="playlist", operation="delete", params={"kind": 1234})provider_write(provider="yandex", entity="playlist", operation="add_tracks", params={"kind": 1234, "track_ids": ["t1","t2"], "revision": <rev>})provider_write(provider="yandex", entity="playlist", operation="remove_tracks", params={"kind": 1234, "track_ids": ["t1"], "revision": <rev>})provider_write(provider="yandex", entity="playlist", operation="set_description", params={"kind": 1234, "description": "..."})provider_write(provider="yandex", entity="likes", operation="add"|"remove", params={"track_ids": [...]})playlist_sync — namespace sync, locked)playlist_sync(playlist_id=<local_id>, direction="diff", source="yandex", dry_run=true)playlist_sync(playlist_id=<local_id>, direction="pull", source="yandex")playlist_sync(playlist_id=<local_id>, direction="push", source="yandex")dry_run=true (default) — preview; pass false to applyNo dedicated tool — compose from primitives:
provider_write(... operation="create" ...)owner:kind pair on the local playlist (dj_playlists.platform_ids) — this is the link the sync tool reads.playlist_sync(playlist_id=<local_playlist_id>, direction="push", dry_run=false)Or use the deliver_set_workflow prompt with sync_to_ym=true.
Each playlist has a source_of_truth field — "local" or "yandex". Sync direction follows source of truth by default; override explicitly via direction.
See @docs/ym-api-guide.md. Highlights:
revision is required for add_tracks / remove_tracks — fetch via provider_read after each mutationplaylist_sync(direction="pull") before building sets from YM-sourced playlistsdry_run=true on sync previews the diff without mutatingtrack_batch, playlist_list) are cheaper than loop-calling per-IDnpx claudepluginhub evgenygurin/dj-music-plugin --plugin dj-musicCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.