@olegkoval/agent-skills 1.35.2 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/.github/copilot-instructions.md +1 -0
  2. package/.github/prompts/music-to-plex.prompt.md +251 -0
  3. package/.kiro/steering/music-to-plex.md +250 -0
  4. package/.windsurf/rules/music-to-plex.md +249 -0
  5. package/README.md +3 -2
  6. package/adapters/claude/olko-creative/skills/music-to-plex/SKILL.md +255 -0
  7. package/adapters/claude/olko-creative/skills/music-to-plex/references/bandcamp-album-identification.md +29 -0
  8. package/adapters/claude/olko-creative/skills/music-to-plex/references/batch-import-staging.md +23 -0
  9. package/adapters/claude/olko-creative/skills/music-to-plex/references/canonical-artist-normalization.md +24 -0
  10. package/adapters/claude/olko-creative/skills/music-to-plex/references/cover-art-and-plexamp.md +22 -0
  11. package/adapters/claude/olko-creative/skills/music-to-plex/references/cover-art-repair-session.md +34 -0
  12. package/adapters/claude/olko-creative/skills/music-to-plex/references/cover-art-sourcing-session.md +23 -0
  13. package/adapters/claude/olko-creative/skills/music-to-plex/references/dj-tracklist-crate-ingest.md +184 -0
  14. package/adapters/claude/olko-creative/skills/music-to-plex/references/duplicate-torrent-handling.md +19 -0
  15. package/adapters/claude/olko-creative/skills/music-to-plex/references/fallback-audio-validation-and-nas-preflight.md +42 -0
  16. package/adapters/claude/olko-creative/skills/music-to-plex/references/gear-change-image-identification.md +35 -0
  17. package/adapters/claude/olko-creative/skills/music-to-plex/references/image-driven-identification-and-verification.md +19 -0
  18. package/adapters/claude/olko-creative/skills/music-to-plex/references/library-repair-folders.md +22 -0
  19. package/adapters/claude/olko-creative/skills/music-to-plex/references/malformed-flac-fallbacks.md +11 -0
  20. package/adapters/claude/olko-creative/skills/music-to-plex/references/manual-fallback-transfer-and-plex-verification.md +39 -0
  21. package/adapters/claude/olko-creative/skills/music-to-plex/references/mtp-bot-bulk-state-safety.md +21 -0
  22. package/adapters/claude/olko-creative/skills/music-to-plex/references/mtp-subprocess-wrapper.md +13 -0
  23. package/adapters/claude/olko-creative/skills/music-to-plex/references/music-note-blurb-order.md +38 -0
  24. package/adapters/claude/olko-creative/skills/music-to-plex/references/nas-import-and-refresh.md +16 -0
  25. package/adapters/claude/olko-creative/skills/music-to-plex/references/nas-library-layout-and-write-preflight.md +31 -0
  26. package/adapters/claude/olko-creative/skills/music-to-plex/references/nas-permissions-and-plex-traversal.md +26 -0
  27. package/adapters/claude/olko-creative/skills/music-to-plex/references/nas-routing-and-refresh.md +22 -0
  28. package/adapters/claude/olko-creative/skills/music-to-plex/references/no-result-album-fallback.md +28 -0
  29. package/adapters/claude/olko-creative/skills/music-to-plex/references/per-track-album-art-split.md +12 -0
  30. package/adapters/claude/olko-creative/skills/music-to-plex/references/plex-playlist-append-and-verify.md +18 -0
  31. package/adapters/claude/olko-creative/skills/music-to-plex/references/plex-playlist-creation.md +21 -0
  32. package/adapters/claude/olko-creative/skills/music-to-plex/references/plex-token-source.md +20 -0
  33. package/adapters/claude/olko-creative/skills/music-to-plex/references/plex-visibility-check.md +28 -0
  34. package/adapters/claude/olko-creative/skills/music-to-plex/references/practice-crate-playlist.md +18 -0
  35. package/adapters/claude/olko-creative/skills/music-to-plex/references/session-2026-06-17-synology-probe.md +13 -0
  36. package/adapters/claude/olko-creative/skills/music-to-plex/references/torrent-stall-fallback.md +62 -0
  37. package/adapters/claude/olko-creative/skills/music-to-plex/references/verification-and-pitfalls.md +17 -0
  38. package/adapters/claude/olko-creative/skills/music-to-plex/references/youtube-403-fallbacks.md +17 -0
  39. package/adapters/claude/olko-creative/skills/music-to-plex/references/youtube-full-album-fallback.md +34 -0
  40. package/adapters/claude/olko-creative/skills/music-to-plex/references/youtube-lineage-playlist-fallback.md +33 -0
  41. package/adapters/claude/olko-creative/skills/music-to-plex/references/youtube-playlist-import.md +50 -0
  42. package/adapters/claude/olko-creative/skills/music-to-plex/references/youtube-track-resolution-heuristics.md +23 -0
  43. package/adapters/claude/olko-creative/skills/music-to-plex/references/zero-track-playlist-recovery.md +21 -0
  44. package/adapters/codex/olko-creative/README.md +1 -0
  45. package/adapters/cursor/olko-creative/skills/music-to-plex/SKILL.md +255 -0
  46. package/adapters/cursor/olko-creative/skills/music-to-plex/references/bandcamp-album-identification.md +29 -0
  47. package/adapters/cursor/olko-creative/skills/music-to-plex/references/batch-import-staging.md +23 -0
  48. package/adapters/cursor/olko-creative/skills/music-to-plex/references/canonical-artist-normalization.md +24 -0
  49. package/adapters/cursor/olko-creative/skills/music-to-plex/references/cover-art-and-plexamp.md +22 -0
  50. package/adapters/cursor/olko-creative/skills/music-to-plex/references/cover-art-repair-session.md +34 -0
  51. package/adapters/cursor/olko-creative/skills/music-to-plex/references/cover-art-sourcing-session.md +23 -0
  52. package/adapters/cursor/olko-creative/skills/music-to-plex/references/dj-tracklist-crate-ingest.md +184 -0
  53. package/adapters/cursor/olko-creative/skills/music-to-plex/references/duplicate-torrent-handling.md +19 -0
  54. package/adapters/cursor/olko-creative/skills/music-to-plex/references/fallback-audio-validation-and-nas-preflight.md +42 -0
  55. package/adapters/cursor/olko-creative/skills/music-to-plex/references/gear-change-image-identification.md +35 -0
  56. package/adapters/cursor/olko-creative/skills/music-to-plex/references/image-driven-identification-and-verification.md +19 -0
  57. package/adapters/cursor/olko-creative/skills/music-to-plex/references/library-repair-folders.md +22 -0
  58. package/adapters/cursor/olko-creative/skills/music-to-plex/references/malformed-flac-fallbacks.md +11 -0
  59. package/adapters/cursor/olko-creative/skills/music-to-plex/references/manual-fallback-transfer-and-plex-verification.md +39 -0
  60. package/adapters/cursor/olko-creative/skills/music-to-plex/references/mtp-bot-bulk-state-safety.md +21 -0
  61. package/adapters/cursor/olko-creative/skills/music-to-plex/references/mtp-subprocess-wrapper.md +13 -0
  62. package/adapters/cursor/olko-creative/skills/music-to-plex/references/music-note-blurb-order.md +38 -0
  63. package/adapters/cursor/olko-creative/skills/music-to-plex/references/nas-import-and-refresh.md +16 -0
  64. package/adapters/cursor/olko-creative/skills/music-to-plex/references/nas-library-layout-and-write-preflight.md +31 -0
  65. package/adapters/cursor/olko-creative/skills/music-to-plex/references/nas-permissions-and-plex-traversal.md +26 -0
  66. package/adapters/cursor/olko-creative/skills/music-to-plex/references/nas-routing-and-refresh.md +22 -0
  67. package/adapters/cursor/olko-creative/skills/music-to-plex/references/no-result-album-fallback.md +28 -0
  68. package/adapters/cursor/olko-creative/skills/music-to-plex/references/per-track-album-art-split.md +12 -0
  69. package/adapters/cursor/olko-creative/skills/music-to-plex/references/plex-playlist-append-and-verify.md +18 -0
  70. package/adapters/cursor/olko-creative/skills/music-to-plex/references/plex-playlist-creation.md +21 -0
  71. package/adapters/cursor/olko-creative/skills/music-to-plex/references/plex-token-source.md +20 -0
  72. package/adapters/cursor/olko-creative/skills/music-to-plex/references/plex-visibility-check.md +28 -0
  73. package/adapters/cursor/olko-creative/skills/music-to-plex/references/practice-crate-playlist.md +18 -0
  74. package/adapters/cursor/olko-creative/skills/music-to-plex/references/session-2026-06-17-synology-probe.md +13 -0
  75. package/adapters/cursor/olko-creative/skills/music-to-plex/references/torrent-stall-fallback.md +62 -0
  76. package/adapters/cursor/olko-creative/skills/music-to-plex/references/verification-and-pitfalls.md +17 -0
  77. package/adapters/cursor/olko-creative/skills/music-to-plex/references/youtube-403-fallbacks.md +17 -0
  78. package/adapters/cursor/olko-creative/skills/music-to-plex/references/youtube-full-album-fallback.md +34 -0
  79. package/adapters/cursor/olko-creative/skills/music-to-plex/references/youtube-lineage-playlist-fallback.md +33 -0
  80. package/adapters/cursor/olko-creative/skills/music-to-plex/references/youtube-playlist-import.md +50 -0
  81. package/adapters/cursor/olko-creative/skills/music-to-plex/references/youtube-track-resolution-heuristics.md +23 -0
  82. package/adapters/cursor/olko-creative/skills/music-to-plex/references/zero-track-playlist-recovery.md +21 -0
  83. package/adapters/grok/olko-creative/skills/music-to-plex/SKILL.md +255 -0
  84. package/adapters/grok/olko-creative/skills/music-to-plex/references/bandcamp-album-identification.md +29 -0
  85. package/adapters/grok/olko-creative/skills/music-to-plex/references/batch-import-staging.md +23 -0
  86. package/adapters/grok/olko-creative/skills/music-to-plex/references/canonical-artist-normalization.md +24 -0
  87. package/adapters/grok/olko-creative/skills/music-to-plex/references/cover-art-and-plexamp.md +22 -0
  88. package/adapters/grok/olko-creative/skills/music-to-plex/references/cover-art-repair-session.md +34 -0
  89. package/adapters/grok/olko-creative/skills/music-to-plex/references/cover-art-sourcing-session.md +23 -0
  90. package/adapters/grok/olko-creative/skills/music-to-plex/references/dj-tracklist-crate-ingest.md +184 -0
  91. package/adapters/grok/olko-creative/skills/music-to-plex/references/duplicate-torrent-handling.md +19 -0
  92. package/adapters/grok/olko-creative/skills/music-to-plex/references/fallback-audio-validation-and-nas-preflight.md +42 -0
  93. package/adapters/grok/olko-creative/skills/music-to-plex/references/gear-change-image-identification.md +35 -0
  94. package/adapters/grok/olko-creative/skills/music-to-plex/references/image-driven-identification-and-verification.md +19 -0
  95. package/adapters/grok/olko-creative/skills/music-to-plex/references/library-repair-folders.md +22 -0
  96. package/adapters/grok/olko-creative/skills/music-to-plex/references/malformed-flac-fallbacks.md +11 -0
  97. package/adapters/grok/olko-creative/skills/music-to-plex/references/manual-fallback-transfer-and-plex-verification.md +39 -0
  98. package/adapters/grok/olko-creative/skills/music-to-plex/references/mtp-bot-bulk-state-safety.md +21 -0
  99. package/adapters/grok/olko-creative/skills/music-to-plex/references/mtp-subprocess-wrapper.md +13 -0
  100. package/adapters/grok/olko-creative/skills/music-to-plex/references/music-note-blurb-order.md +38 -0
  101. package/adapters/grok/olko-creative/skills/music-to-plex/references/nas-import-and-refresh.md +16 -0
  102. package/adapters/grok/olko-creative/skills/music-to-plex/references/nas-library-layout-and-write-preflight.md +31 -0
  103. package/adapters/grok/olko-creative/skills/music-to-plex/references/nas-permissions-and-plex-traversal.md +26 -0
  104. package/adapters/grok/olko-creative/skills/music-to-plex/references/nas-routing-and-refresh.md +22 -0
  105. package/adapters/grok/olko-creative/skills/music-to-plex/references/no-result-album-fallback.md +28 -0
  106. package/adapters/grok/olko-creative/skills/music-to-plex/references/per-track-album-art-split.md +12 -0
  107. package/adapters/grok/olko-creative/skills/music-to-plex/references/plex-playlist-append-and-verify.md +18 -0
  108. package/adapters/grok/olko-creative/skills/music-to-plex/references/plex-playlist-creation.md +21 -0
  109. package/adapters/grok/olko-creative/skills/music-to-plex/references/plex-token-source.md +20 -0
  110. package/adapters/grok/olko-creative/skills/music-to-plex/references/plex-visibility-check.md +28 -0
  111. package/adapters/grok/olko-creative/skills/music-to-plex/references/practice-crate-playlist.md +18 -0
  112. package/adapters/grok/olko-creative/skills/music-to-plex/references/session-2026-06-17-synology-probe.md +13 -0
  113. package/adapters/grok/olko-creative/skills/music-to-plex/references/torrent-stall-fallback.md +62 -0
  114. package/adapters/grok/olko-creative/skills/music-to-plex/references/verification-and-pitfalls.md +17 -0
  115. package/adapters/grok/olko-creative/skills/music-to-plex/references/youtube-403-fallbacks.md +17 -0
  116. package/adapters/grok/olko-creative/skills/music-to-plex/references/youtube-full-album-fallback.md +34 -0
  117. package/adapters/grok/olko-creative/skills/music-to-plex/references/youtube-lineage-playlist-fallback.md +33 -0
  118. package/adapters/grok/olko-creative/skills/music-to-plex/references/youtube-playlist-import.md +50 -0
  119. package/adapters/grok/olko-creative/skills/music-to-plex/references/youtube-track-resolution-heuristics.md +23 -0
  120. package/adapters/grok/olko-creative/skills/music-to-plex/references/zero-track-playlist-recovery.md +21 -0
  121. package/catalog/skills.json +33 -9
  122. package/docs/versioning.md +4 -2
  123. package/package.json +1 -1
  124. package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
  125. package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
  126. package/plugins/olko-creative/skills/music-to-plex/SKILL.md +254 -0
  127. package/plugins/olko-creative/skills/music-to-plex/references/bandcamp-album-identification.md +29 -0
  128. package/plugins/olko-creative/skills/music-to-plex/references/batch-import-staging.md +23 -0
  129. package/plugins/olko-creative/skills/music-to-plex/references/canonical-artist-normalization.md +24 -0
  130. package/plugins/olko-creative/skills/music-to-plex/references/cover-art-and-plexamp.md +22 -0
  131. package/plugins/olko-creative/skills/music-to-plex/references/cover-art-repair-session.md +34 -0
  132. package/plugins/olko-creative/skills/music-to-plex/references/cover-art-sourcing-session.md +23 -0
  133. package/plugins/olko-creative/skills/music-to-plex/references/dj-tracklist-crate-ingest.md +184 -0
  134. package/plugins/olko-creative/skills/music-to-plex/references/duplicate-torrent-handling.md +19 -0
  135. package/plugins/olko-creative/skills/music-to-plex/references/fallback-audio-validation-and-nas-preflight.md +42 -0
  136. package/plugins/olko-creative/skills/music-to-plex/references/gear-change-image-identification.md +35 -0
  137. package/plugins/olko-creative/skills/music-to-plex/references/image-driven-identification-and-verification.md +19 -0
  138. package/plugins/olko-creative/skills/music-to-plex/references/library-repair-folders.md +22 -0
  139. package/plugins/olko-creative/skills/music-to-plex/references/malformed-flac-fallbacks.md +11 -0
  140. package/plugins/olko-creative/skills/music-to-plex/references/manual-fallback-transfer-and-plex-verification.md +39 -0
  141. package/plugins/olko-creative/skills/music-to-plex/references/mtp-bot-bulk-state-safety.md +21 -0
  142. package/plugins/olko-creative/skills/music-to-plex/references/mtp-subprocess-wrapper.md +13 -0
  143. package/plugins/olko-creative/skills/music-to-plex/references/music-note-blurb-order.md +38 -0
  144. package/plugins/olko-creative/skills/music-to-plex/references/nas-import-and-refresh.md +16 -0
  145. package/plugins/olko-creative/skills/music-to-plex/references/nas-library-layout-and-write-preflight.md +31 -0
  146. package/plugins/olko-creative/skills/music-to-plex/references/nas-permissions-and-plex-traversal.md +26 -0
  147. package/plugins/olko-creative/skills/music-to-plex/references/nas-routing-and-refresh.md +22 -0
  148. package/plugins/olko-creative/skills/music-to-plex/references/no-result-album-fallback.md +28 -0
  149. package/plugins/olko-creative/skills/music-to-plex/references/per-track-album-art-split.md +12 -0
  150. package/plugins/olko-creative/skills/music-to-plex/references/plex-playlist-append-and-verify.md +18 -0
  151. package/plugins/olko-creative/skills/music-to-plex/references/plex-playlist-creation.md +21 -0
  152. package/plugins/olko-creative/skills/music-to-plex/references/plex-token-source.md +20 -0
  153. package/plugins/olko-creative/skills/music-to-plex/references/plex-visibility-check.md +28 -0
  154. package/plugins/olko-creative/skills/music-to-plex/references/practice-crate-playlist.md +18 -0
  155. package/plugins/olko-creative/skills/music-to-plex/references/session-2026-06-17-synology-probe.md +13 -0
  156. package/plugins/olko-creative/skills/music-to-plex/references/torrent-stall-fallback.md +62 -0
  157. package/plugins/olko-creative/skills/music-to-plex/references/verification-and-pitfalls.md +17 -0
  158. package/plugins/olko-creative/skills/music-to-plex/references/youtube-403-fallbacks.md +17 -0
  159. package/plugins/olko-creative/skills/music-to-plex/references/youtube-full-album-fallback.md +34 -0
  160. package/plugins/olko-creative/skills/music-to-plex/references/youtube-lineage-playlist-fallback.md +33 -0
  161. package/plugins/olko-creative/skills/music-to-plex/references/youtube-playlist-import.md +50 -0
  162. package/plugins/olko-creative/skills/music-to-plex/references/youtube-track-resolution-heuristics.md +23 -0
  163. package/plugins/olko-creative/skills/music-to-plex/references/zero-track-playlist-recovery.md +21 -0
  164. package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
  165. package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
  166. package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
  167. package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
  168. package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
  169. package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
  170. package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
  171. package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
  172. package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
  173. package/scripts/lib/catalog.mjs +1 -1
@@ -0,0 +1,249 @@
1
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
2
+
3
+ ---
4
+ description: "Acquire music and make it playable in Plex/Plexamp: single albums, DJ crates, and YouTube playlists, with verified NAS/Plex delivery and source-backed Obsidian radio notes."
5
+ ---
6
+
7
+ # Music to Plex
8
+
9
+ Acquire music and surface it in Plex/Plexamp. Three flows: **album** (one-shot
10
+ via `mtp-bot`), **DJ tracklist/crate**, and **YouTube playlist**. Pick the flow,
11
+ run it, verify, post notes.
12
+
13
+ ## Operating rules (non-negotiable)
14
+
15
+ - **One command per album.** For a single album/release, call `mtp-bot handle`
16
+ once and post its output. Do **not** run `mtp search`/`add`/`status` yourself,
17
+ do **not** pick a version (auto-pick is automatic), do **not** poll for
18
+ download status (the notifier streams it).
19
+ - **Serialize multi-album imports.** `mtp-bot` keeps a state machine per chat;
20
+ never dispatch album handler calls in parallel. Send one request, inspect its
21
+ reply, and proceed only after it has accepted the release or returned to idle.
22
+ If it opens a numbered picker, stop the batch and preserve that picker until
23
+ its owner chooses or explicitly authorizes cancellation. Do not send a bare
24
+ number, `cancel`, or a new request into an existing picker on behalf of a
25
+ different request. **Exception:** when the user explicitly says to ignore or
26
+ override an active download and names the replacement, treat that as direct
27
+ cancellation authority: dispatch the resolved replacement once, without a
28
+ redundant confirmation loop, and state that the earlier job may be abandoned.
29
+ - **Route by shape.** Album → `mtp-bot handle`. DJ tracklist/crate → the crate
30
+ ingest reference. YouTube playlist or plain track list → the YouTube flow.
31
+ Never pass a crate or multi-track prose to `mtp-bot handle` (album-shaped
32
+ parser; it will reply `⏭️ Not a music album request — skipped.`).
33
+ - **Cover-art requests need resolution before dispatch.** A bare `mtp` with an
34
+ album image is an explicit album request, but `mtp` alone is not handler-ready.
35
+ Transcribe/identify the cover, verify the canonical release and track count,
36
+ then proceed through the resolved-image continuation. Never expect the album
37
+ parser to infer a title from an image caption. When invoking `mtp-bot`, use the
38
+ **originating Telegram chat ID** from the inbound route; a group ID, user ID,
39
+ and configured home-chat ID are different things.
40
+ - **Never claim done without verification.** A "Downloading…" or a successful Plex refresh is a *start* signal, not proof. The album is done only when the files exist under the configured Plex library path **and** are visible in Plexamp. Read back playlist items before saying a playlist is updated.
41
+ - **Show the user the checklist.** For every album ingest, post/update this exact evidence-led checklist in order. Mark `✅` only after tool evidence; use `⏳` while active, `⚠️` for a verified blocker, and never silently omit a step:
42
+ ```text
43
+ ⏳ Canonical release metadata / tracklist verified
44
+ ⏳ Audio acquired and locally staged
45
+ ⏳ Track count, tags, embedded art, and file integrity verified
46
+ ⏳ NAS artist-path and write-permission preflight verified
47
+ ⏳ Files copied to the final Plex-scanned NAS folder
48
+ ⏳ NAS count/art/folder traversal verified; transfer sidecars cleaned
49
+ ⏳ Plex refresh triggered and album + full track count read back from Plex
50
+ ⏳ Obsidian note written: Artist note → Album note → DJ summary
51
+ ```
52
+ The final response must retain this checklist with concrete proof values (final path, counts, Plex result, and note path). If a fallback bypasses the normal handler, say so explicitly and still keep the checklist.
53
+ - **Never fabricate facts.** In DJ notes, if unsure of a musician/label/year, say less. Do not invent files, APIs, env vars, or NAS paths.
54
+ - **Obsidian note voice and substance.** Notes must use the full enrichment standard in `references/music-note-blurb-order.md`: original WFMU / LDBK / Radio Brussels / classic-underground-radio energy, vivid sensory language, and juicy source-backed facts that make listeners curious and emotionally engaged. Include verified recording/release context, label/year, collaborators/producers, samples or scene links, unusual backstory, cultural impact, and concrete listening cues when available. Never imitate a named presenter, write generic promo copy, or pad the note with unsourced trivia. Run the replaceability test before saving: if the note would mostly work after swapping the album name, rewrite it.
55
+ - **Obsidian vault path.** Write music notes to `/Users/olegkoval/Documents/opus/Music/`, the visible Music folder used by the existing notes (not `Documents/opus/Obsidian/Hermes/Music/`). Verify the exact note path by reading it back after writing.
56
+ - **Secrets live in `~/.config/music-to-plex/.env`** (loaded automatically by
57
+ `Config.load`), never in `config.toml`. If a check says "PLEX_TOKEN not set",
58
+ fix the `.env`. See `references/plex-token-source.md`.
59
+ - **Hand off repair.** Album on disk but not visible, wrong folder/tags after
60
+ the fact, bulk library cleanup, permission problems, or Plex scanner/DB
61
+ crashes → this is **plex-music-ingest**'s job, not this skill's.
62
+
63
+ ## One-shot album flow
64
+
65
+ The user posts once ("add <album>") and gets a status stream back. The mechanics
66
+ (auto-pick best version, download, organize, Plex refresh, staged status
67
+ messages) are handled by the tool chain. **Your only creative job is the DJ
68
+ blurb.**
69
+
70
+ ### Step 1 — Run the handler once
71
+
72
+ ```bash
73
+ mtp-bot handle "<exact user message>" --chat <chat_id>
74
+ ```
75
+
76
+ `<exact user message>` = what the user said; `<chat_id>` = the Telegram chat ID.
77
+ This auto-picks the highest-seed release, starts the download, and spawns a
78
+ background notifier. It returns:
79
+
80
+ ```
81
+ ✅ Accepted: <Artist> — <Album>
82
+ ⏳ Downloading [FORMAT] SIZE, N seeds — status updates to follow.
83
+ ```
84
+
85
+ Post that result as-is.
86
+
87
+ ### Step 2 — Write the notes in strict order
88
+
89
+ Immediately after posting "Accepted", while the download runs in the background,
90
+ write one enrichment package, in this order:
91
+
92
+ 1. **Artist note** — a specific, substantial paragraph in the original WFMU / LDBK / Radio Brussels / classic-underground-radio lane: the artist's broader sound, history, scene, collaborators, and lane. Include at least one verified fact that gives the listener a reason to care.
93
+ 2. **Album note** — a separate, juicy paragraph: year, label, recording/release context, key players, unusual backstory, samples or scene connections, cultural impact, and two or three concrete things to listen for. Use only facts verified from authoritative sources; turn them into a human invitation rather than a database dump.
94
+ 3. Optional one-line DJ summary or recommendation — tactile, specific, curious, and emotionally inviting.
95
+
96
+ Keep artist note first and album note second — never merge them into one generic promo paragraph. Sound like a great late-night radio host with a crate-digger’s memory, not a press release or a Wikipedia entry. See
97
+ `references/music-note-blurb-order.md`. Optional extras: 🎵 YouTube link,
98
+ `🎶 You might also like:` + 2 short recommendations.
99
+
100
+ ### Step 3 — Let the notifier stream the rest
101
+
102
+ The background notifier posts these on its own — **do not poll or re-run**:
103
+
104
+ ```
105
+ 📥 Downloaded → 📂 Moving to library folder → 🔄 Rescanning Plex → ✅ Ready in Plexamp
106
+ ```
107
+
108
+ After "Ready", mirror the notes into the canonical visible Music vault at
109
+ `/Users/olegkoval/Documents/opus/Music/` as a music note for that release
110
+ (append if it exists), artist note above album note, followed by DJ summary and
111
+ source links. Read the exact file back before reporting the note complete. If
112
+ the user asked for album art, save the release image as `cover.jpg` in the
113
+ artist/release folder and verify it exists. See
114
+ `references/cover-art-sourcing-session.md`.
115
+
116
+ ### Step 4 — Follow-up replies (stuck downloads)
117
+
118
+ If a download stalls, the notifier posts a "stuck" message with 4 numbered
119
+ options (wait 1h / wait N hours / next release / YouTube). When the user replies
120
+ — a bare number `1`–`4`, a count of hours, or "next" / "youtube" — **pass the
121
+ reply verbatim to `mtp-bot handle`**, exactly like an add request. Post whatever
122
+ it returns.
123
+
124
+ **YouTube handoff:** if `mtp-bot handle` returns a line starting with
125
+ `__YOUTUBE_FALLBACK__`, strip it and run the YouTube flow yourself (download
126
+ highest-quality audio with `yt-dlp`, fix tags, move into the library, refresh
127
+ Plex), then post the blurb. If `rsync` or `scp` is unsuitable for a release transfer, use the verified tar-over-SSH fallback, remove any macOS AppleDouble sidecars, and compare NAS/Plex track counts with canonical metadata. See `references/manual-fallback-transfer-and-plex-verification.md`, `references/youtube-403-fallbacks.md`, and `references/youtube-full-album-fallback.md`.
128
+
129
+ **No-result continuation:** if the bot returns an actual no-results outcome and
130
+ the user asks to continue, do not stop at a blocker report. Resolve canonical
131
+ MusicBrainz metadata, then run the fail-closed track-by-track YouTube fallback:
132
+ match each track by normalized title and duration, reject videos/remixes/live
133
+ versions unless canonical, tag and cover-embed every file, stage it, transfer,
134
+ and verify in Plex. A file's existence is not evidence it completed: fully decode
135
+ all staged files and compare each actual duration to canonical metadata before
136
+ NAS transfer; re-tag the full set after any interrupted run. Prefer separately
137
+ sourced tracks over slicing a continuous full-album upload; only split a full
138
+ upload using validated cues and boundary checks. Clearly distinguish local
139
+ staging, NAS transfer, and Plex visibility. See
140
+ `references/no-result-album-fallback.md` and
141
+ `references/fallback-audio-validation-and-nas-preflight.md`.
142
+
143
+ ### Manual-fallback NAS preflight
144
+
145
+ Resolve the canonical release first, then preflight the exact NAS destination
146
+ **in parallel with source selection and before substantial fallback downloading**.
147
+ Inspect the NAS layout and an existing album by the same artist. `nas_music` is a
148
+ storage root, not proof that a new artist directory is inside the Plex-scanned
149
+ library. Confirm the originating transfer account can write and traverse the
150
+ exact final parent; if a new artist directory is required, confirm it can create
151
+ that directory too. If the parent is root-owned or read-only, do not spend the
152
+ whole fallback download hoping the copy will work and do not invent an alternate
153
+ writable folder. Keep any already-staged release local and request an
154
+ album-scoped permission repair from the NAS owner.
155
+
156
+ **Durable access repair:** when the user explicitly wants future managed imports
157
+ to work, repair the *Plex library root* (for this setup,
158
+ `/volume1/music/library`) rather than recursively changing ownership of the
159
+ whole `/volume1/music` share. A safe target is managed-account ownership and
160
+ library-root group write (for example `beheerder:users`, `775`), then verify by
161
+ creating and removing a uniquely named probe directory over SSH. New artist and
162
+ album parents must still be Plex-traversable (`755`); an artist directory left
163
+ at `770` can block scanner traversal even when the release directory and FLACs
164
+ are readable. Never widen ownership/permissions above the Plex library root
165
+ without explicit user approval. See
166
+ `references/nas-library-layout-and-write-preflight.md`,
167
+ `references/fallback-audio-validation-and-nas-preflight.md`, and
168
+ `references/nas-permissions-and-plex-traversal.md`.
169
+
170
+ ## DJ tracklist / crate flow
171
+
172
+ A timestamped DJ set or a themed crate brief is **not** an album request. Parse
173
+ the list, find lawful sources, acquire audio when allowed, fix metadata/artwork,
174
+ store a separate DJ-friendly folder on NAS, and create/refresh a Plex playlist.
175
+ Creation is incomplete until Plex shows a visible playlist **and** the crate has
176
+ proper cover art. If the user says the set is for DJ practice, treat it as a
177
+ **practice crate**: rebuild/trim for mixability, don't just append tracks. Full
178
+ procedure: `references/dj-tracklist-crate-ingest.md`.
179
+
180
+ ## YouTube playlist flow
181
+
182
+ Use when the user wants a YouTube playlist (not a timestamped DJ set, not a
183
+ single album) turned into a normal Plex listening playlist. Two inputs: a
184
+ ready-made playlist URL, or a plain list of `Artist - Title` lines. Do not route
185
+ through `mtp-bot handle` or the crate flow. Full download/tagging/placement/
186
+ verification steps: `references/youtube-playlist-import.md`.
187
+
188
+ ## Verification pitfalls (hard-won)
189
+
190
+ - **File exists ≠ visible.** After refresh, if Plexamp shows nothing, re-verify
191
+ the album landed under the configured Plex-rooted library path (not a staging/
192
+ download dir or a bucket Plex doesn't scan). See `references/plex-visibility-check.md`.
193
+ - **Permissions.** Root-owned `700` directories are invisible to Plex traversal
194
+ even if the audio is readable. Verify the final folder is traversable and fix
195
+ to `755` before every refresh.
196
+ - **Refresh verb.** On this Plex install, `/library/sections/{id}/refresh` must
197
+ be **GET**; PUT returns 404, and a targeted `path=` refresh may also 404 - fall
198
+ back to a plain section refresh. Refresh only after files are in their final
199
+ NAS path; refresh again after any later tag/rename change.
200
+ - **Targeted refresh exists in the CLI.** `mtp refresh --path <final NAS path>`
201
+ is the preferred completion check when the release lands cleanly. Treat
202
+ `{"refreshed": true, "section_id": ...}` as a real success signal.
203
+
204
+ - **Target layout beats generic configuration.** Before creating a genre bucket, inspect where Plex stores an existing album from the same artist and confirm the transfer account can write that parent. Do not redirect a release to an unrelated writable folder or `unsorted` solely to make the copy succeed; repair access to the canonical target instead. See `references/nas-library-layout-and-write-preflight.md`.
205
+ - **Corrupt source ≠ Plex problem.** If a chapter-based rip yields a zero-byte or
206
+ corrupt final track, switch source first, then tag and move — don't just
207
+ re-refresh. See `references/malformed-flac-fallbacks.md`.
208
+ - **NAS codec tools may be unavailable.** Some NAS images ship neither `ffprobe`
209
+ nor an AAC decoder in `ffmpeg`. In that case, fully decode each staged source
210
+ locally before transfer, then use NAS file count/art/sidecar/traversal checks
211
+ plus Plex’s album-and-track read-back as the remote verification receipt. Do
212
+ not describe a remote decode as passed when the NAS tool cannot decode it.
213
+ - **Duplicate torrent.** On Synology `Duplicate torrent file`, do not retry
214
+ blindly — `list_tasks` first; repeated attempts stack failed tasks. Clean stale
215
+ tasks, then re-search with plain artist/album text (no magnet URLs in replies).
216
+ See `references/duplicate-torrent-handling.md`.
217
+ - **Image/typo identification.** If the user sends cover art or a misspelled/clip
218
+ title (`Single`, `Official clip`, `teaser`), use it as a *clue* — confirm the
219
+ real release name and track count on the store/release page before importing.
220
+ See `references/image-driven-identification-and-verification.md` and
221
+ `references/bandcamp-album-identification.md`.
222
+ - **Lesson (scanner health):** when an album repeatedly "won't ingest" after the
223
+ files are correctly placed, stop re-moving files. The cause is usually scanner/
224
+ DB state, not placement — a direct scanner probe can crash with `DB::Exception`
225
+ while a plain refresh succeeds. At that point the album is a **plex-music-ingest**
226
+ case: check scanner health, DB state, and crash cause before touching tags again.
227
+ (Real example: an album sat correctly at `/volume1/music/Various Artists/…`
228
+ yet stayed invisible; extra nested `library/pop` layers never helped.)
229
+
230
+ ## References
231
+
232
+ - Notes & enrichment: `music-note-blurb-order.md`, `cover-art-sourcing-session.md`
233
+ - Album ID & verification: `image-driven-identification-and-verification.md`,
234
+ `gear-change-image-identification.md`, `bandcamp-album-identification.md`,
235
+ `plex-visibility-check.md`, `verification-and-pitfalls.md`
236
+ - DJ crates: `dj-tracklist-crate-ingest.md`, `cover-art-repair-session.md`,
237
+ `per-track-album-art-split.md`, `youtube-lineage-playlist-fallback.md`
238
+ - YouTube: `youtube-playlist-import.md`, `youtube-403-fallbacks.md`,
239
+ `youtube-full-album-fallback.md`, `fallback-audio-validation-and-nas-preflight.md`
240
+ - Playlists: `plex-playlist-creation.md`, `plex-playlist-append-and-verify.md`,
241
+ `zero-track-playlist-recovery.md`
242
+ - Plex/NAS plumbing: `plex-token-source.md`, `nas-routing-and-refresh.md`,
243
+ `batch-import-staging.md`, `mtp-subprocess-wrapper.md`,
244
+ `mtp-bot-bulk-state-safety.md`, `session-2026-06-17-synology-probe.md`
245
+ - Repair/forensics (mostly owned by **plex-music-ingest**):
246
+ `library-repair-folders.md`, `canonical-artist-normalization.md`,
247
+ `cover-art-and-plexamp.md`
248
+
249
+ That is the skill. Pick the flow, run it, verify, post notes. Silence if no output.
package/README.md CHANGED
@@ -259,14 +259,15 @@ Build, test and publish Garmin Connect IQ watch faces.
259
259
  |-------|-------------|----------|
260
260
  | [garmin-watchface](plugins/olko-garmin-kit/skills/garmin-watchface/SKILL.md) | Designs, builds, tests, screenshots, and publishes Garmin Connect IQ watch faces in Monkey C | Working on a Connect IQ watch face, SVG design proposals, inspiration gathering, layout that clips or overlaps, simulator screenshots, app settings, device support, or store submission |
261
261
 
262
- ### olko-creative (4)
262
+ ### olko-creative (5)
263
263
 
264
- Creative and personal projects: photo galleries, music players, listings, wiki editing.
264
+ Creative and personal projects: photo galleries, music players, Plex ingest, listings, wiki editing.
265
265
 
266
266
  | Skill | What it does | Use when |
267
267
  |-------|-------------|----------|
268
268
  | [gallery](plugins/olko-creative/skills/gallery/SKILL.md) | Creates photo galleries with AI-assisted layout curation and sequencing | Building a gallery from photos or planning photo layout, sequencing, and curation |
269
269
  | [fill-music-player](plugins/olko-creative/skills/fill-music-player/SKILL.md) | Fills a portable music player with a curated random selection while balancing formats, artists, albums, and capacity | Copying music from a NAS or local library to a Walkman, iPod, USB drive, or similar device |
270
+ | [music-to-plex](plugins/olko-creative/skills/music-to-plex/SKILL.md) | Acquires albums, DJ crates, and YouTube playlists for Plex/Plexamp with verified NAS delivery, Plex visibility, and source-backed Obsidian radio notes | Adding or downloading music to Plex/Plexamp, including an album request, DJ crate, or YouTube playlist |
270
271
  | [vinted-listing](plugins/olko-creative/skills/vinted-listing/SKILL.md) | Creates and safely publishes Vinted listings from verified item details and the seller’s original photos, with automatic suggestions, duplicate checks, draft verification, and publish confirmation | Creating, editing, or publishing a Vinted listing |
271
272
  | [wikipedia-uk-editor](plugins/olko-creative/skills/wikipedia-uk-editor/SKILL.md) | Drafts policy-compliant Ukrainian Wikipedia edits, en→uk translation, stub expansion, sourcing, backlog cleanup, returning ready-to-paste wikitext, an edit summary, and a verified source list | Editing, translating, or sourcing a uk.wikipedia.org article, or planning what to contribute next |
272
273
 
@@ -0,0 +1,255 @@
1
+ ---
2
+ name: music-to-plex
3
+ description: "Acquire music and make it playable in Plex/Plexamp — single albums (via mtp-bot), DJ tracklists/crates, and YouTube playlists. Use ONLY when the user explicitly wants to ADD or DOWNLOAD music to Plex (e.g. 'add to Plex', 'get me this album', 'download this playlist', a timestamped DJ tracklist, or a plain 'Artist - Title' list). NOT for podcasts or non-music; for albums already on disk that won't show up, bulk library repair, or Plex scanner/DB problems, hand off to plex-music-ingest."
4
+ version: 3.0.0
5
+ platforms: [macos, linux]
6
+ metadata:
7
+ hermes:
8
+ tags: [music, plex, flac, nas, synology, album, playlist, plexamp]
9
+ related_skills: [plex-music-ingest, music-library-publishing, music-note-curation, podcast-monitoring]
10
+ ---
11
+ <!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
12
+
13
+ # Music to Plex
14
+
15
+ Acquire music and surface it in Plex/Plexamp. Three flows: **album** (one-shot
16
+ via `mtp-bot`), **DJ tracklist/crate**, and **YouTube playlist**. Pick the flow,
17
+ run it, verify, post notes.
18
+
19
+ ## Operating rules (non-negotiable)
20
+
21
+ - **One command per album.** For a single album/release, call `mtp-bot handle`
22
+ once and post its output. Do **not** run `mtp search`/`add`/`status` yourself,
23
+ do **not** pick a version (auto-pick is automatic), do **not** poll for
24
+ download status (the notifier streams it).
25
+ - **Serialize multi-album imports.** `mtp-bot` keeps a state machine per chat;
26
+ never dispatch album handler calls in parallel. Send one request, inspect its
27
+ reply, and proceed only after it has accepted the release or returned to idle.
28
+ If it opens a numbered picker, stop the batch and preserve that picker until
29
+ its owner chooses or explicitly authorizes cancellation. Do not send a bare
30
+ number, `cancel`, or a new request into an existing picker on behalf of a
31
+ different request. **Exception:** when the user explicitly says to ignore or
32
+ override an active download and names the replacement, treat that as direct
33
+ cancellation authority: dispatch the resolved replacement once, without a
34
+ redundant confirmation loop, and state that the earlier job may be abandoned.
35
+ - **Route by shape.** Album → `mtp-bot handle`. DJ tracklist/crate → the crate
36
+ ingest reference. YouTube playlist or plain track list → the YouTube flow.
37
+ Never pass a crate or multi-track prose to `mtp-bot handle` (album-shaped
38
+ parser; it will reply `⏭️ Not a music album request — skipped.`).
39
+ - **Cover-art requests need resolution before dispatch.** A bare `mtp` with an
40
+ album image is an explicit album request, but `mtp` alone is not handler-ready.
41
+ Transcribe/identify the cover, verify the canonical release and track count,
42
+ then proceed through the resolved-image continuation. Never expect the album
43
+ parser to infer a title from an image caption. When invoking `mtp-bot`, use the
44
+ **originating Telegram chat ID** from the inbound route; a group ID, user ID,
45
+ and configured home-chat ID are different things.
46
+ - **Never claim done without verification.** A "Downloading…" or a successful Plex refresh is a *start* signal, not proof. The album is done only when the files exist under the configured Plex library path **and** are visible in Plexamp. Read back playlist items before saying a playlist is updated.
47
+ - **Show the user the checklist.** For every album ingest, post/update this exact evidence-led checklist in order. Mark `✅` only after tool evidence; use `⏳` while active, `⚠️` for a verified blocker, and never silently omit a step:
48
+ ```text
49
+ ⏳ Canonical release metadata / tracklist verified
50
+ ⏳ Audio acquired and locally staged
51
+ ⏳ Track count, tags, embedded art, and file integrity verified
52
+ ⏳ NAS artist-path and write-permission preflight verified
53
+ ⏳ Files copied to the final Plex-scanned NAS folder
54
+ ⏳ NAS count/art/folder traversal verified; transfer sidecars cleaned
55
+ ⏳ Plex refresh triggered and album + full track count read back from Plex
56
+ ⏳ Obsidian note written: Artist note → Album note → DJ summary
57
+ ```
58
+ The final response must retain this checklist with concrete proof values (final path, counts, Plex result, and note path). If a fallback bypasses the normal handler, say so explicitly and still keep the checklist.
59
+ - **Never fabricate facts.** In DJ notes, if unsure of a musician/label/year, say less. Do not invent files, APIs, env vars, or NAS paths.
60
+ - **Obsidian note voice and substance.** Notes must use the full enrichment standard in `references/music-note-blurb-order.md`: original WFMU / LDBK / Radio Brussels / classic-underground-radio energy, vivid sensory language, and juicy source-backed facts that make listeners curious and emotionally engaged. Include verified recording/release context, label/year, collaborators/producers, samples or scene links, unusual backstory, cultural impact, and concrete listening cues when available. Never imitate a named presenter, write generic promo copy, or pad the note with unsourced trivia. Run the replaceability test before saving: if the note would mostly work after swapping the album name, rewrite it.
61
+ - **Obsidian vault path.** Write music notes to `/Users/olegkoval/Documents/opus/Music/`, the visible Music folder used by the existing notes (not `Documents/opus/Obsidian/Hermes/Music/`). Verify the exact note path by reading it back after writing.
62
+ - **Secrets live in `~/.config/music-to-plex/.env`** (loaded automatically by
63
+ `Config.load`), never in `config.toml`. If a check says "PLEX_TOKEN not set",
64
+ fix the `.env`. See `references/plex-token-source.md`.
65
+ - **Hand off repair.** Album on disk but not visible, wrong folder/tags after
66
+ the fact, bulk library cleanup, permission problems, or Plex scanner/DB
67
+ crashes → this is **plex-music-ingest**'s job, not this skill's.
68
+
69
+ ## One-shot album flow
70
+
71
+ The user posts once ("add <album>") and gets a status stream back. The mechanics
72
+ (auto-pick best version, download, organize, Plex refresh, staged status
73
+ messages) are handled by the tool chain. **Your only creative job is the DJ
74
+ blurb.**
75
+
76
+ ### Step 1 — Run the handler once
77
+
78
+ ```bash
79
+ mtp-bot handle "<exact user message>" --chat <chat_id>
80
+ ```
81
+
82
+ `<exact user message>` = what the user said; `<chat_id>` = the Telegram chat ID.
83
+ This auto-picks the highest-seed release, starts the download, and spawns a
84
+ background notifier. It returns:
85
+
86
+ ```
87
+ ✅ Accepted: <Artist> — <Album>
88
+ ⏳ Downloading [FORMAT] SIZE, N seeds — status updates to follow.
89
+ ```
90
+
91
+ Post that result as-is.
92
+
93
+ ### Step 2 — Write the notes in strict order
94
+
95
+ Immediately after posting "Accepted", while the download runs in the background,
96
+ write one enrichment package, in this order:
97
+
98
+ 1. **Artist note** — a specific, substantial paragraph in the original WFMU / LDBK / Radio Brussels / classic-underground-radio lane: the artist's broader sound, history, scene, collaborators, and lane. Include at least one verified fact that gives the listener a reason to care.
99
+ 2. **Album note** — a separate, juicy paragraph: year, label, recording/release context, key players, unusual backstory, samples or scene connections, cultural impact, and two or three concrete things to listen for. Use only facts verified from authoritative sources; turn them into a human invitation rather than a database dump.
100
+ 3. Optional one-line DJ summary or recommendation — tactile, specific, curious, and emotionally inviting.
101
+
102
+ Keep artist note first and album note second — never merge them into one generic promo paragraph. Sound like a great late-night radio host with a crate-digger’s memory, not a press release or a Wikipedia entry. See
103
+ `references/music-note-blurb-order.md`. Optional extras: 🎵 YouTube link,
104
+ `🎶 You might also like:` + 2 short recommendations.
105
+
106
+ ### Step 3 — Let the notifier stream the rest
107
+
108
+ The background notifier posts these on its own — **do not poll or re-run**:
109
+
110
+ ```
111
+ 📥 Downloaded → 📂 Moving to library folder → 🔄 Rescanning Plex → ✅ Ready in Plexamp
112
+ ```
113
+
114
+ After "Ready", mirror the notes into the canonical visible Music vault at
115
+ `/Users/olegkoval/Documents/opus/Music/` as a music note for that release
116
+ (append if it exists), artist note above album note, followed by DJ summary and
117
+ source links. Read the exact file back before reporting the note complete. If
118
+ the user asked for album art, save the release image as `cover.jpg` in the
119
+ artist/release folder and verify it exists. See
120
+ `references/cover-art-sourcing-session.md`.
121
+
122
+ ### Step 4 — Follow-up replies (stuck downloads)
123
+
124
+ If a download stalls, the notifier posts a "stuck" message with 4 numbered
125
+ options (wait 1h / wait N hours / next release / YouTube). When the user replies
126
+ — a bare number `1`–`4`, a count of hours, or "next" / "youtube" — **pass the
127
+ reply verbatim to `mtp-bot handle`**, exactly like an add request. Post whatever
128
+ it returns.
129
+
130
+ **YouTube handoff:** if `mtp-bot handle` returns a line starting with
131
+ `__YOUTUBE_FALLBACK__`, strip it and run the YouTube flow yourself (download
132
+ highest-quality audio with `yt-dlp`, fix tags, move into the library, refresh
133
+ Plex), then post the blurb. If `rsync` or `scp` is unsuitable for a release transfer, use the verified tar-over-SSH fallback, remove any macOS AppleDouble sidecars, and compare NAS/Plex track counts with canonical metadata. See `references/manual-fallback-transfer-and-plex-verification.md`, `references/youtube-403-fallbacks.md`, and `references/youtube-full-album-fallback.md`.
134
+
135
+ **No-result continuation:** if the bot returns an actual no-results outcome and
136
+ the user asks to continue, do not stop at a blocker report. Resolve canonical
137
+ MusicBrainz metadata, then run the fail-closed track-by-track YouTube fallback:
138
+ match each track by normalized title and duration, reject videos/remixes/live
139
+ versions unless canonical, tag and cover-embed every file, stage it, transfer,
140
+ and verify in Plex. A file's existence is not evidence it completed: fully decode
141
+ all staged files and compare each actual duration to canonical metadata before
142
+ NAS transfer; re-tag the full set after any interrupted run. Prefer separately
143
+ sourced tracks over slicing a continuous full-album upload; only split a full
144
+ upload using validated cues and boundary checks. Clearly distinguish local
145
+ staging, NAS transfer, and Plex visibility. See
146
+ `references/no-result-album-fallback.md` and
147
+ `references/fallback-audio-validation-and-nas-preflight.md`.
148
+
149
+ ### Manual-fallback NAS preflight
150
+
151
+ Resolve the canonical release first, then preflight the exact NAS destination
152
+ **in parallel with source selection and before substantial fallback downloading**.
153
+ Inspect the NAS layout and an existing album by the same artist. `nas_music` is a
154
+ storage root, not proof that a new artist directory is inside the Plex-scanned
155
+ library. Confirm the originating transfer account can write and traverse the
156
+ exact final parent; if a new artist directory is required, confirm it can create
157
+ that directory too. If the parent is root-owned or read-only, do not spend the
158
+ whole fallback download hoping the copy will work and do not invent an alternate
159
+ writable folder. Keep any already-staged release local and request an
160
+ album-scoped permission repair from the NAS owner.
161
+
162
+ **Durable access repair:** when the user explicitly wants future managed imports
163
+ to work, repair the *Plex library root* (for this setup,
164
+ `/volume1/music/library`) rather than recursively changing ownership of the
165
+ whole `/volume1/music` share. A safe target is managed-account ownership and
166
+ library-root group write (for example `beheerder:users`, `775`), then verify by
167
+ creating and removing a uniquely named probe directory over SSH. New artist and
168
+ album parents must still be Plex-traversable (`755`); an artist directory left
169
+ at `770` can block scanner traversal even when the release directory and FLACs
170
+ are readable. Never widen ownership/permissions above the Plex library root
171
+ without explicit user approval. See
172
+ `references/nas-library-layout-and-write-preflight.md`,
173
+ `references/fallback-audio-validation-and-nas-preflight.md`, and
174
+ `references/nas-permissions-and-plex-traversal.md`.
175
+
176
+ ## DJ tracklist / crate flow
177
+
178
+ A timestamped DJ set or a themed crate brief is **not** an album request. Parse
179
+ the list, find lawful sources, acquire audio when allowed, fix metadata/artwork,
180
+ store a separate DJ-friendly folder on NAS, and create/refresh a Plex playlist.
181
+ Creation is incomplete until Plex shows a visible playlist **and** the crate has
182
+ proper cover art. If the user says the set is for DJ practice, treat it as a
183
+ **practice crate**: rebuild/trim for mixability, don't just append tracks. Full
184
+ procedure: `references/dj-tracklist-crate-ingest.md`.
185
+
186
+ ## YouTube playlist flow
187
+
188
+ Use when the user wants a YouTube playlist (not a timestamped DJ set, not a
189
+ single album) turned into a normal Plex listening playlist. Two inputs: a
190
+ ready-made playlist URL, or a plain list of `Artist - Title` lines. Do not route
191
+ through `mtp-bot handle` or the crate flow. Full download/tagging/placement/
192
+ verification steps: `references/youtube-playlist-import.md`.
193
+
194
+ ## Verification pitfalls (hard-won)
195
+
196
+ - **File exists ≠ visible.** After refresh, if Plexamp shows nothing, re-verify
197
+ the album landed under the configured Plex-rooted library path (not a staging/
198
+ download dir or a bucket Plex doesn't scan). See `references/plex-visibility-check.md`.
199
+ - **Permissions.** Root-owned `700` directories are invisible to Plex traversal
200
+ even if the audio is readable. Verify the final folder is traversable and fix
201
+ to `755` before every refresh.
202
+ - **Refresh verb.** On this Plex install, `/library/sections/{id}/refresh` must
203
+ be **GET**; PUT returns 404, and a targeted `path=` refresh may also 404 - fall
204
+ back to a plain section refresh. Refresh only after files are in their final
205
+ NAS path; refresh again after any later tag/rename change.
206
+ - **Targeted refresh exists in the CLI.** `mtp refresh --path <final NAS path>`
207
+ is the preferred completion check when the release lands cleanly. Treat
208
+ `{"refreshed": true, "section_id": ...}` as a real success signal.
209
+
210
+ - **Target layout beats generic configuration.** Before creating a genre bucket, inspect where Plex stores an existing album from the same artist and confirm the transfer account can write that parent. Do not redirect a release to an unrelated writable folder or `unsorted` solely to make the copy succeed; repair access to the canonical target instead. See `references/nas-library-layout-and-write-preflight.md`.
211
+ - **Corrupt source ≠ Plex problem.** If a chapter-based rip yields a zero-byte or
212
+ corrupt final track, switch source first, then tag and move — don't just
213
+ re-refresh. See `references/malformed-flac-fallbacks.md`.
214
+ - **NAS codec tools may be unavailable.** Some NAS images ship neither `ffprobe`
215
+ nor an AAC decoder in `ffmpeg`. In that case, fully decode each staged source
216
+ locally before transfer, then use NAS file count/art/sidecar/traversal checks
217
+ plus Plex’s album-and-track read-back as the remote verification receipt. Do
218
+ not describe a remote decode as passed when the NAS tool cannot decode it.
219
+ - **Duplicate torrent.** On Synology `Duplicate torrent file`, do not retry
220
+ blindly — `list_tasks` first; repeated attempts stack failed tasks. Clean stale
221
+ tasks, then re-search with plain artist/album text (no magnet URLs in replies).
222
+ See `references/duplicate-torrent-handling.md`.
223
+ - **Image/typo identification.** If the user sends cover art or a misspelled/clip
224
+ title (`Single`, `Official clip`, `teaser`), use it as a *clue* — confirm the
225
+ real release name and track count on the store/release page before importing.
226
+ See `references/image-driven-identification-and-verification.md` and
227
+ `references/bandcamp-album-identification.md`.
228
+ - **Lesson (scanner health):** when an album repeatedly "won't ingest" after the
229
+ files are correctly placed, stop re-moving files. The cause is usually scanner/
230
+ DB state, not placement — a direct scanner probe can crash with `DB::Exception`
231
+ while a plain refresh succeeds. At that point the album is a **plex-music-ingest**
232
+ case: check scanner health, DB state, and crash cause before touching tags again.
233
+ (Real example: an album sat correctly at `/volume1/music/Various Artists/…`
234
+ yet stayed invisible; extra nested `library/pop` layers never helped.)
235
+
236
+ ## References
237
+
238
+ - Notes & enrichment: `music-note-blurb-order.md`, `cover-art-sourcing-session.md`
239
+ - Album ID & verification: `image-driven-identification-and-verification.md`,
240
+ `gear-change-image-identification.md`, `bandcamp-album-identification.md`,
241
+ `plex-visibility-check.md`, `verification-and-pitfalls.md`
242
+ - DJ crates: `dj-tracklist-crate-ingest.md`, `cover-art-repair-session.md`,
243
+ `per-track-album-art-split.md`, `youtube-lineage-playlist-fallback.md`
244
+ - YouTube: `youtube-playlist-import.md`, `youtube-403-fallbacks.md`,
245
+ `youtube-full-album-fallback.md`, `fallback-audio-validation-and-nas-preflight.md`
246
+ - Playlists: `plex-playlist-creation.md`, `plex-playlist-append-and-verify.md`,
247
+ `zero-track-playlist-recovery.md`
248
+ - Plex/NAS plumbing: `plex-token-source.md`, `nas-routing-and-refresh.md`,
249
+ `batch-import-staging.md`, `mtp-subprocess-wrapper.md`,
250
+ `mtp-bot-bulk-state-safety.md`, `session-2026-06-17-synology-probe.md`
251
+ - Repair/forensics (mostly owned by **plex-music-ingest**):
252
+ `library-repair-folders.md`, `canonical-artist-normalization.md`,
253
+ `cover-art-and-plexamp.md`
254
+
255
+ That is the skill. Pick the flow, run it, verify, post notes. Silence if no output.
@@ -0,0 +1,29 @@
1
+ # Bandcamp album identification when OCR/YouTube points at a single
2
+
3
+ Use this when cover art or a clip title points to a song, but the user actually wants the full release.
4
+
5
+ ## Pattern from this session
6
+
7
+ - Cover art text said `74 Miles Away - Gear Change`.
8
+ - A YouTube clip title looked like a single: `74 Miles Away - Gear Change // Single`.
9
+ - The Bandcamp release page was the source of truth:
10
+ - `https://74milesaway.bandcamp.com/album/gear-change`
11
+ - page title: `Gear Change | 74 Miles Away`
12
+ - tracklist: 8 tracks
13
+ - release date: `2013-05-16`
14
+ - `yt-dlp -J` on the Bandcamp album URL exposed the album metadata directly:
15
+ - `playlist_title = Gear Change`
16
+ - `playlist_count = 8`
17
+ - `album = Gear Change`
18
+ - `album_artist = 74 Miles Away`
19
+
20
+ ## Practical rule
21
+
22
+ If the clip title includes `Single`, `Official clip`, or another video-oriented label, do not treat it as the final release name. Check the Bandcamp album page (or equivalent store page) for the actual album title and track count before importing.
23
+
24
+ ## Verification
25
+
26
+ - Prefer the album page over a clip title.
27
+ - Use `yt-dlp -J <album-url>` to confirm the release title and track list.
28
+ - Import the full album folder, not the clip single, before refreshing Plex.
29
+ - Verify the album in Plex by searching the music section for the album title after refresh.
@@ -0,0 +1,23 @@
1
+ # Batch import staging and source validation
2
+
3
+ Use this pattern when importing multiple albums from downloaded source material into Plex.
4
+
5
+ ## Stage-first workflow
6
+
7
+ 1. Stage each album in a temp tree before touching the NAS library path.
8
+ 2. After staging, push the staged tree into the final NAS location in one shot.
9
+ 3. Normalize final permissions before refresh:
10
+ - album directories: `755`
11
+ - audio files and art: `644`
12
+ 4. Refresh Plex only after the final path and permissions are correct.
13
+ 5. Verify Plex search for album and at least one track after refresh.
14
+
15
+ ## Source validation for YouTube rips
16
+
17
+ - Prefer a source with reliable chapter metadata when the album is chapter-based.
18
+ - If the first candidate download produces a bad last track or an invalid MP3, do not keep tagging it. Treat that as a source problem and try an alternate full-album upload instead.
19
+ - Sanity-check extracted audio before tagging or moving it into the library. A quick `ffprobe` or `file` pass on each MP3 is enough to catch a corrupt final track.
20
+
21
+ ## Practical fallback
22
+
23
+ If the local machine cannot write to the NAS library path directly, keep the staging tree local and stream it to the NAS over SSH, then run the permission normalization and Plex refresh remotely.
@@ -0,0 +1,24 @@
1
+ # Canonical artist normalization
2
+
3
+ Session note for bulk metadata repair and folder convergence.
4
+
5
+ ## Rule
6
+ When multiple artist spellings refer to one real artist, normalize them to a single canonical display name before writing tags or deciding folder placement.
7
+
8
+ Example from this session:
9
+ - Canonical display name: `Godspeed You! Black Emperor`
10
+ - Collapsed variants included punctuation/no-punctuation spellings such as `godspeedyoublackemperor`, `Godspeed You Black Emperor!`, and `Godspeed You! Black Emperor`
11
+
12
+ ## Practical pattern
13
+ - Normalize artist strings by stripping non-alphanumerics for lookup.
14
+ - Apply the canonical mapping in two places:
15
+ - when choosing the dominant artist for a directory or album batch
16
+ - when comparing existing tags before deciding whether to rewrite them
17
+ - If the normalized value differs from the current tag, treat it as drift and rewrite the tag so the library converges.
18
+
19
+ ## Why this matters
20
+ - Plex can surface the same artist multiple times when tags disagree on punctuation or spacing.
21
+ - Folder names and tags need to converge on the same canonical form or future refreshes keep re-splitting the library.
22
+
23
+ ## Implementation note
24
+ If the normalizer is generated inside an outer f-string, escape literal braces in embedded dicts with `{{ ... }}` so the generator does not try to interpret the mapping as formatting syntax.
@@ -0,0 +1,22 @@
1
+ # Cover art and PlexAmp visibility
2
+
3
+ Session note: when a music release is imported from a chapter-split source or a plain audio rip, the album may index in Plex with no artwork because there is no local cover image and Plex cannot reliably match the release online.
4
+
5
+ ## Practical rule
6
+
7
+ If PlexAmp shows the album but the tile is blank or generic:
8
+ 1. Check the final album folder for a local image first (`cover.jpg`, `folder.jpg`, `front.jpg`, or `*.png`).
9
+ 2. If none exists, fetch the real release art from Discogs or another authoritative release listing and place it in the album folder as `cover.jpg`.
10
+ 3. Prefer the exact release art over YouTube thumbnails, generic web images, or a random match.
11
+ 4. Refresh the Plex music section again after the art file is in place.
12
+ 5. Prefer folder art for compilation releases and niche albums that Plex metadata matching may not recognize.
13
+
14
+ ## Useful note
15
+
16
+ A clean import can still be missing art. That is not the same failure as library ingest. Treat artwork as a separate visibility layer from track indexing.
17
+
18
+ ## Discogs workflow
19
+
20
+ - Search Discogs by the exact album title and year.
21
+ - Open the release page or API record, then use the release image for the final folder art.
22
+ - Verify the art file on disk after copy, then refresh Plex and re-check PlexAmp.