Help us improve
Share bugs, ideas, or general feedback.
From dj-music
This skill should be used when the user asks to expand a playlist, find similar tracks, add more tracks, discover new tracks, import from Yandex Music, or fill gaps in a playlist. Covers discovery, feedback gating, import, download and analysis.
npx claudepluginhub evgenygurin/dj-music-plugin --plugin dj-musicHow this skill is triggered — by the user, by Claude, or both
Slash command
/dj-music:expand-playlistThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide the user through discovering and importing new tracks via the v1 polymorphic dispatchers. See @docs/tool-catalog.md (**20 tools** = 14 core dispatchers + 6 UI Prefab + 27 resources + 6 prompts).
Applies 10 pre-set color/font themes or generates custom ones for slides, documents, reports, and HTML landing pages.
Share bugs, ideas, or general feedback.
Guide the user through discovering and importing new tracks via the v1 polymorphic dispatchers. See @docs/tool-catalog.md (20 tools = 14 core dispatchers + 6 UI Prefab + 27 resources + 6 prompts).
Use the expand_playlist_workflow prompt — it chains audit → discover → feedback gate → import → download → analyze → classify:
expand_playlist_workflow(source_playlist_id=<id>, target_count=100, genre_filter=["techno"], dry_run=true)
Run once with dry_run=true to preview, then again without it.
Audit current playlist
local://playlists/{id}/audit — full quality check, gap report, BPM/key/subgenre coverageFind similar tracks (YM recommendations) per seed:
provider_read(provider="yandex", entity="track_similar", id=<ym_track_id>, params={"limit": 20})provider_search(provider="yandex", query="Amelie Lens acid techno", type="tracks", limit=20)expand_playlist_workflow prompt (it asks Claude for search queries, then feeds them to provider_search) — see @.claude/rules/llm-sampling.mdFilter candidates by feedback (dedupe / drop disliked / boost liked)
Track has no external_id column directly — provider IDs live in track_external_ids (relation external_ids). Resolve by calling provider_read(provider="yandex", entity="track_batch", params={"track_ids": [...]}) to fetch metadata, then dedupe via entity_list(entity="track", filters={"id__in": [...]}) once you have local IDs. For YM specifically, the YandexMetadata join exposes yandex_track_id — query via the yandex_metadata relation if you've imported them.entity_list(entity="track_feedback", filters={"track_id__in": [...]}, fields="full") (after import) or via raw provider id through the feedback model's external link.Review candidates
provider_read(provider="yandex", entity="track", id=<ym_id>)Import selected tracks
entity_create(entity="track", data={"ym_ids": ["12345", "67890"], "playlist_id": <pid>})
(handler track_import fetches metadata from YM, creates Track + YandexMetadata + RawProviderResponse, links to playlist)Download MP3s (needed for DJ software / L4 delivery)
entity_create(entity="audio_file", data={"track_ids": [...], "persistent": true})
(handler audio_file_download — writes to DJ_YM_LIBRARY_PATH, links DjLibraryItem, idempotent)Analyze new tracks (L1+L2 — mood classification lands in features)
entity_create(entity="track_features", data={"track_ids": [...], "level": 2})level=3; for L4 structure: level=4.entity_update(entity="track_features", id=<fid>, data={"level": 3})Re-audit
local://playlists/{id}/audit again — compare coverage before / afterEnd-to-end chain via prompt (audit → discover → import → download → analyze → classify → distribute):
full_pipeline(source_playlist_id=<id>, target_per_subgenre=40)
provider_search and provider_read are in the provider:read namespace — visible by default; no unlock neededentity_create(entity="track", ...) covers import; entity_create(entity="audio_file", ...) covers download; entity_create(entity="track_features", ...) covers analysis — three separate side-effect handlers, not one monolithdeliver_set — iCloud stubs (<90% size) cannot be copiedtransition_score_pool(track_ids=[...])