From 08757f152fec9c36eca4f90c815ef31fdfe344a6 Mon Sep 17 00:00:00 2001 From: minimax Date: Tue, 14 Apr 2026 00:01:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(minimax-music-playlist):=20v2.1=20?= =?UTF-8?q?=E2=80=94=20privacy-first=20data=20collection=20&=20legal=20com?= =?UTF-8?q?pliance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace direct app querying (osascript) with user-exported data only. Add consent prompts, PII stripping for Spotify data, opt-in MusicBrainz lookup, Apple Music privacy portal export flow, and local music library ID3 tag support. Co-Authored-By: Claude Opus 4.6 (1M context) --- skills/minimax-music-playlist/SKILL.md | 137 +++++++++++++++++++++---- 1 file changed, 116 insertions(+), 21 deletions(-) diff --git a/skills/minimax-music-playlist/SKILL.md b/skills/minimax-music-playlist/SKILL.md index 61bf62fe..bc979e10 100644 --- a/skills/minimax-music-playlist/SKILL.md +++ b/skills/minimax-music-playlist/SKILL.md @@ -8,20 +8,21 @@ description: > any language. license: MIT metadata: - version: "2.0" + version: "2.1" category: creative --- # MiniMax Music Playlist — Personalized Playlist Generator -Scan the user's music taste, build a taste profile, generate a personalized +Analyze the user's music taste, build a taste profile, generate a personalized playlist, and create an album cover. This skill is designed for both agent and direct user invocation — adapt interaction style to context. + ## Prerequisites - **mmx CLI** — music & image generation. Install: `npm install -g mmx-cli`. Auth: `mmx auth login --api-key `. -- **Python 3** — for scanning scripts you write on the fly (stdlib only, no pip). +- **Python 3** — for data parsing scripts you write on the fly (stdlib only, no pip). - **Audio player** — `mpv`, `ffplay`, or `afplay` (macOS built-in). ## Language @@ -40,7 +41,7 @@ NOT the user's UI language. ## Workflow ``` -1. Scan local music apps → 2. Build taste profile → 3. Plan playlist +1. Import user-exported data → 2. Build taste profile → 3. Plan playlist → 4. Generate songs (mmx music) → 5. Generate cover (mmx image) → 6. Play → 7. Save & feedback ``` @@ -48,17 +49,61 @@ NOT the user's UI language. ## Step 1: Gather Music Listening Data -Collect the user's listening data from available sources. +Collect the user's listening data from **user-initiated exports only**. This tool +does NOT directly query or scrape any streaming service application. + +**Important:** Before processing any data, display a consent prompt: +``` +This tool will analyze your exported music listening data to build a taste +profile for playlist generation. The data stays on your machine and is not +uploaded anywhere. Only the final song generation prompts (containing no +personal data) are sent to MiniMax's API. + +Proceed? (y/n) +``` +Only continue if the user confirms. **Supported sources:** | Source | Method | Data format | |--------|--------|-------------| -| Apple Music | `osascript` to query Music.app (official AppleScript interface) | Track name, artist, album, genre, play count | -| Spotify | User exports their own data via [Spotify Privacy Settings](https://www.spotify.com/account/privacy/) | JSON files in ZIP (`Streaming_History_Audio_*.json`) | +| Apple Music | User exports via [Apple Privacy Portal](https://privacy.apple.com/) | CSV/JSON files in ZIP | +| Spotify | User exports via [Spotify Privacy Settings](https://www.spotify.com/account/privacy/) | JSON files in ZIP (`Streaming_History_Audio_*.json`) | +| Local music library | Read local `.mp3`/`.flac` files' ID3 metadata (user's own files) | ID3 tags | | Manual input | User describes their taste directly | Free text | -**Spotify data export flow:** +### Apple Music data export flow + +Apple provides an official data export through its privacy portal. This is the +**only** supported method for Apple Music data — do NOT use `osascript`, Music.app +AppleScript, or any other programmatic querying of Apple's applications or services. + +1. Search for existing exports: `find ~ -maxdepth 4 -name "Apple_Media_Services.zip" -o -name "Apple Music - Play History.csv" -o -name "Apple Music Play Activity.csv" 2>/dev/null` +2. If found, ask the user if they want to use it +3. If not found, open Apple's privacy page: `open https://privacy.apple.com/` +4. Tell the user to: + - Log in with their Apple Account + - Select "Request a copy of your data" + - Check "Apple Media Services information" (this includes Apple Music history) + - Submit the request +5. Apple typically delivers the export within 1–7 days +6. Skip Apple Music for now and continue with other sources — tell the user they + can re-run the playlist skill after the export arrives + +**Apple Music data format:** +The export typically contains CSV files such as `Apple Music - Play History.csv` +or `Apple Music Play Activity.csv`. Key fields to extract: +- `Track Description` or `Song Name` — track name +- `Artist Name` — artist +- `Container Description` or `Album` — album name +- `Genre` — genre (if available) +- `Play Duration Milliseconds` or `Media Duration In Milliseconds` — playback duration +- `Event Start Timestamp` or `Activity date (UTC)` — timestamp + +Filter out entries with very short play durations (< 30 seconds, likely skipped). + +### Spotify data export flow + Spotify does not store useful data locally. To include Spotify listening history, first check if the user already has a Spotify data export: @@ -80,26 +125,45 @@ is a JSON array of listening events. Key fields to extract: - `ts` — timestamp Filter out entries where `ms_played < 30000` (less than 30 seconds, likely skipped). -Do NOT use or store `ip_addr` or other sensitive fields. + +**PII stripping (mandatory):** Before any processing or caching of Spotify data, +explicitly remove the following fields from each record: `ip_addr`, +`conn_country`, `user_agent_decrypted`, `platform`, `incognito_mode`. +Use a whitelist approach — only keep the five fields listed above, discard +everything else. + +### Local music library + +As a fallback, read the user's local music files (`~/Music/` or user-specified +directory) and read ID3 tags (artist, title, album, genre) using Python's stdlib. +This only reads the user's own files and does not interact with any streaming service. + +### Manual input + +If no exports are available, ask the user to describe their taste: favorite +artists, genres, moods, and any recent songs they enjoyed. **What to extract from each source:** - Track names + artist names (primary signal) -- Playlist names and membership (e.g., a playlist named "Chinese Traditional" tells you genre preference) +- Genre tags if available - Play counts or streaming duration if available (weight frequently played tracks higher) - Scene/mood tags if available **Approach:** -1. Check if Apple Music is available (try `osascript` query) -2. Ask if the user has a Spotify data export ZIP to provide -3. If no sources available, ask the user to describe their taste manually +1. Ask which sources the user has available (Apple export, Spotify export, local files) +2. For each available source, locate and parse the exported data +3. If no sources available, fall back to manual input -**Privacy rule:** Never show raw track lists to the user. Only show aggregated stats. +**Privacy rules:** +- Never show raw track lists to the user — only show aggregated stats +- Never cache or log raw export file paths that may contain usernames +- All cached profiles must be deletable via `--purge` (see Step 7) --- ## Step 2: Build Taste Profile -From the scanned data, build a taste profile covering: +From the imported data, build a taste profile covering: - **Genre distribution** — what styles the user listens to (e.g., J-pop 20%, R&B 15%, Classical 10%) - **Mood tendencies** — emotional tone preferences (melancholic, energetic, calm, romantic, etc.) @@ -112,21 +176,43 @@ From the scanned data, build a taste profile covering: Most raw data only has artist + track names without genre tags. To enrich this: 1. Look up artists in the local mapping table at `/data/artist_genre_map.json` — this table covers 20,000 popular artists with pre-mapped genres, vocal type, and language -2. For artists not in the mapping table, query the MusicBrainz API: - `https://musicbrainz.org/ws/2/artist/?query=artist:&fmt=json` +2. If an artist is not found in the mapping table, skip it and continue + +**Optional: MusicBrainz enrichment (opt-in only)** + +After the local lookup is complete, if some artists could not be matched, +prompt the user: + +``` +Some artists in your library could not be identified using the local database. +You can enable MusicBrainz lookup to fill in the missing genre information. +MusicBrainz is a third-party open music database. Its API is free for +non-commercial use. Commercial use is subject to their license terms: +https://musicbrainz.org/doc/About/Data_License +Enable MusicBrainz lookup? (y/n) +``` + +Only if the user confirms, query the MusicBrainz API for unmatched artists: + `https://musicbrainz.org/ws/2/artist/?query=artist:&fmt=json` — extract genre tags from the response; respect rate limit (1 req/sec) + — **must** set a descriptive User-Agent header per MusicBrainz API policy, + e.g., `User-Agent: minimax-music-playlist/2.1 (https://github.com/your-org/repo)` — cache results to `/data/artist_cache.json` to avoid re-querying -3. If MusicBrainz returns no results, skip the artist + — if MusicBrainz returns no results for an artist, skip it + +Do NOT call the MusicBrainz API without explicit user consent. The skill +must function fully without MusicBrainz — it is a supplementary data source, +not a required dependency. **Profile caching:** - Save profile to `/data/taste_profile.json` -- If a profile less than 7 days old exists, reuse it (offer rescan option) +- If a profile less than 7 days old exists, reuse it (offer rebuild option) - If older or missing, rebuild **Show user a summary:** ``` Your Music Profile: - Sources: Apple Music 230 | Spotify 140 + Sources: Apple Music export (230 tracks) | Spotify export (140 tracks) Genres: J-pop 20% | R&B 15% | Classical 10% | Indie Pop 9% Moods: Melancholic 25% | Calm 20% | Romantic 18% Vocals: Female 65% | Male 35% @@ -304,6 +390,11 @@ If the user is present, ask for feedback (per-song or overall). Update the taste profile's feedback section with liked/disliked genres and prompts to improve future playlists. +**Data management:** +- `--purge-profile` — delete only the taste profile: `rm /data/taste_profile.json` +- Cached data is stored only in `/data/` — no data is written elsewhere +- No raw export data is ever cached — only aggregated profiles and artist metadata + --- ## Replaying Playlists @@ -318,8 +409,12 @@ available ones, and play the selected one. - **Agent vs user invocation**: The theme/scene question (Step 3) is the single interactive touchpoint. If the theme is already provided in the invocation, skip the question. Everything else runs autonomously. -- **No hardcoded scripts**: Write scanning/analysis scripts on the fly as needed. +- **No hardcoded scripts**: Write parsing and analysis scripts on the fly as needed. Use Python stdlib only. Cache results to avoid redundant work. - **Skill directory**: `` = the directory containing this SKILL.md file. Data/cache files go in `/data/`. - **All mmx prompts in English** for best generation quality. +- **No osascript / no direct app querying**: This tool does not use `osascript`, + AppleScript, or any programmatic interface to query Music.app, Spotify.app, or + any other streaming service application. All data come from user-initiated + exports or local file metadata.