[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C36BMECTZDP9Y89ZJJRMPT":3,"skill-same:01M6C36BMECTZDP9Y89ZJJRMPT":72},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":29,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":53,"ownerHtmlUrl":54,"ownerBlogUrl":55,"ownerDescription":56,"updatedAt":57,"install":58,"resources":71},"01M6C36BMECTZDP9Y89ZJJRMPT","cover-art-embedding",null,"Patterns for finding, processing, and embedding cover artwork into media files","jmagly\u002Faiwg","jmagly","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1159087?v=4","01M6C10AK8N2WCSQN11FYGTJWN","Joseph Magly","01M6C10AQ8A2RMED1Y1BSVY7NF",229,"MIT","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fmedia-curator\u002Fskills\u002Fcover-art-embedding\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[30,31,32,33,34,35,36,37,38],"cover art embedding","Art","embedding","cover","Media","files","patterns","processing","for","2026-11-10 10:12:30",false,"---\nnamespace: aiwg\nplatforms: [all]\nname: cover-art-embedding\ndescription: Patterns for finding, processing, and embedding cover artwork into media files\ncategory: media-curator\n---\n\n# Cover Art Embedding Skill\n\nConcrete patterns for finding high-quality cover artwork, processing it for optimal size and format, and embedding it into audio and video files.\n\n## Artwork Sources\n\n### MusicBrainz Cover Art Archive (Primary)\n\nMusicBrainz Cover Art Archive (CAA) is the authoritative source for album artwork.\n\n**Get Front Cover by Release MBID**:\n```bash\n# Download front cover for a release\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o cover.jpg\n\n# Example with real MBID\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F5c004fe3-6e96-3f43-9a85-16e5be8805fa\u002Ffront\" -o blue-cover.jpg\n```\n\n**Check if Cover Exists**:\n```bash\n# HEAD request to check without downloading\nif curl -s -I \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" | grep -q \"200 OK\"; then\n  echo \"Cover available\"\nelse\n  echo \"No cover found\"\nfi\n```\n\n**Get All Available Images**:\n```bash\n# Get metadata for all images\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | jq .\n\n# Extract URLs for all front covers\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | \\\n  jq -r '.images[] | select(.front == true) | .image'\n\n# Download highest resolution front cover\nurl=$(curl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | \\\n  jq -r '.images[] | select(.front == true) | .image' | head -1)\ncurl -s \"$url\" -o cover.jpg\n```\n\n### fanart.tv API\n\nfanart.tv provides high-quality artist images, album covers, and logos.\n\n**Get Artist Images**:\n```bash\n# Requires API key from https:\u002F\u002Ffanart.tv\u002Fget-an-api-key\u002F\nFANART_API_KEY=\"your-api-key\"\n\n# Get all artist artwork\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\"\n\n# Extract album cover URLs\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url'\n\n# Extract artist background\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.artistbackground[0].url'\n\n# Extract artist logo\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.hdmusiclogo[0].url'\n```\n\n**Download Artwork**:\n```bash\n# Download album cover\nurl=$(curl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url')\ncurl -s \"$url\" -o cover.jpg\n```\n\n### Video Thumbnail Extraction\n\nExtract cover artwork from video frames.\n\n**Using yt-dlp** (if video was downloaded with thumbnail):\n```bash\n# Download video with thumbnail\nyt-dlp --write-thumbnail --convert-thumbnails jpg \"https:\u002F\u002Fyoutube.com\u002Fwatch?v=...\"\n\n# Result: video.jpg alongside video.mp4\n```\n\n**Using ffmpeg** (extract from video):\n```bash\n# Extract single frame at specific time\nffmpeg -i input.mp4 -ss 00:00:10 -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract I-frame (best quality)\nffmpeg -i input.mp4 -vf \"select=eq(pict_type\\,I)\" -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract frame at 25% into video\nduration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4)\ntimestamp=$(echo \"$duration * 0.25\" | bc)\nffmpeg -i input.mp4 -ss \"$timestamp\" -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract highest quality frame from first minute\nffmpeg -i input.mp4 -t 60 -vf \"select=eq(pict_type\\,I)\" -vsync vfr -q:v 1 frames-%03d.jpg\n# Then manually select best frame\n```\n\n### Local Artwork Files\n\nScan for existing artwork in standard locations:\n\n```bash\n# Check for common filenames in album directory\nfor name in cover.jpg Cover.jpg folder.jpg Folder.jpg albumart.jpg AlbumArt.jpg; do\n  if [ -f \"$name\" ]; then\n    echo \"Found: $name\"\n    break\n  fi\ndone\n\n# Search parent directory\nif [ -f \"..\u002Fcover.jpg\" ]; then\n  cp \"..\u002Fcover.jpg\" .\nfi\n\n# Find largest image file (likely the cover)\nlargest=$(find . -maxdepth 1 -type f \\( -iname \"*.jpg\" -o -iname \"*.png\" \\) -exec ls -s {} \\; | \\\n  sort -rn | head -1 | awk '{print $2}')\necho \"Largest image: $largest\"\n```\n\n## Image Processing\n\n### Resize for Mobile Optimization\n\nReduce image size for faster loading and smaller file sizes:\n\n```bash\n# Install ImageMagick\nbrew install imagemagick  # macOS\nsudo apt install imagemagick  # Debian\u002FUbuntu\n\n# Resize to 1200x1200 max (preserves aspect ratio)\nconvert input.jpg -resize 1200x1200 output.jpg\n\n# Resize and optimize quality (85% JPEG quality)\nconvert input.jpg -resize 1200x1200 -quality 85 output.jpg\n\n# Create thumbnail (300x300)\nconvert input.jpg -resize 300x300 thumbnail.jpg\n\n# Batch resize all images in directory\nfor img in *.jpg; do\n  convert \"$img\" -resize 1200x1200 -quality 85 \"${img%.jpg}-resized.jpg\"\ndone\n```\n\n### Format Conversion\n\nConvert between image formats:\n\n```bash\n# PNG to JPEG\nconvert input.png output.jpg\n\n# WebP to JPEG\nconvert input.webp output.jpg\n\n# JPEG to PNG (lossless)\nconvert input.jpg output.png\n\n# Batch convert all PNG to JPEG\nfor img in *.png; do\n  convert \"$img\" \"${img%.png}.jpg\"\ndone\n```\n\n### Crop to Square\n\nCrop non-square images to square aspect ratio:\n\n```bash\n# Center crop to square\nconvert input.jpg -gravity center -crop 1:1 +repage output.jpg\n\n# Crop from top-left\nconvert input.jpg -crop 1200x1200+0+0 +repage output.jpg\n\n# Smart crop (removes boring edges)\nconvert input.jpg -define trim:percent-background=0% -trim +repage -resize 1200x1200 output.jpg\n```\n\n### Remove Metadata (Privacy)\n\nStrip EXIF data before embedding:\n\n```bash\n# Remove all metadata\nconvert input.jpg -strip output.jpg\n\n# Or use exiftool\nexiftool -all= input.jpg\n\n# Batch strip metadata\nfor img in *.jpg; do\n  convert \"$img\" -strip \"${img%.jpg}-clean.jpg\"\ndone\n```\n\n## Embedding Artwork\n\n### Opus Files (opustags)\n\n```bash\n# Embed cover art from JPEG file\nopustags input.opus --set-cover cover.jpg -o output.opus\n\n# In-place embedding\nopustags -i input.opus --set-cover cover.jpg\n\n# Verify embedding\nopustags input.opus | grep -i picture\n```\n\n### MP4 Files (ffmpeg)\n\n```bash\n# Embed cover as attached picture\nffmpeg -i input.mp4 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:1 attached_pic \\\n  output.mp4\n\n# Embed with metadata\nffmpeg -i input.mp4 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:1 attached_pic \\\n  -metadata:s:v:1 title=\"Album cover\" \\\n  -metadata:s:v:1 comment=\"Cover (front)\" \\\n  output.mp4\n\n# Verify embedding\nffprobe -v error -select_streams v -show_entries stream=codec_name,codec_type,disposition input.mp4\n```\n\n### MP3 Files (ffmpeg)\n\n```bash\n# Embed cover with ID3v2.3\nffmpeg -i input.mp3 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -id3v2_version 3 \\\n  -metadata:s:v title=\"Album cover\" \\\n  -metadata:s:v comment=\"Cover (front)\" \\\n  output.mp3\n\n# Verify embedding\nffmpeg -i input.mp3 -an -vcodec copy test-extracted-cover.jpg\n```\n\n### FLAC Files (ffmpeg)\n\n```bash\n# Embed cover into FLAC\nffmpeg -i input.flac -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:0 attached_pic \\\n  output.flac\n\n# Using metaflac (alternative)\nmetaflac --import-picture-from=cover.jpg input.flac\n```\n\n## Batch Embedding\n\n### Embed Same Cover into All Files\n\n```bash\n# Opus files in directory\nfor file in *.opus; do\n  opustags -i \"$file\" --set-cover cover.jpg\n  echo \"Embedded: $file\"\ndone\n\n# MP3 files in directory\nfor file in *.mp3; do\n  ffmpeg -i \"$file\" -i cover.jpg \\\n    -map 0 -map 1 -c copy \\\n    -id3v2_version 3 \\\n    -metadata:s:v title=\"Album cover\" \\\n    \"${file%.mp3}-covered.mp3\"\n  mv \"${file%.mp3}-covered.mp3\" \"$file\"\ndone\n```\n\n### Embed Different Covers per Album\n\n```bash\n# Process album directories\nfor album_dir in *\u002F; do\n  # Find cover in album directory\n  cover=$(find \"$album_dir\" -maxdepth 1 -iname \"cover.jpg\" | head -1)\n\n  if [ -n \"$cover\" ]; then\n    # Embed into all Opus files in this album\n    for file in \"$album_dir\"\u002F*.opus; do\n      opustags -i \"$file\" --set-cover \"$cover\"\n    done\n    echo \"Processed: $album_dir\"\n  else\n    echo \"No cover found: $album_dir\"\n  fi\ndone\n```\n\n### Download and Embed from MusicBrainz\n\n```bash\n#!\u002Fbin\u002Fbash\n# Process all Opus files, download covers, embed\n\nfor file in *.opus; do\n  # Extract artist and album from tags\n  artist=$(opustags \"$file\" | grep \"ARTIST=\" | cut -d= -f2)\n  album=$(opustags \"$file\" | grep \"ALBUM=\" | cut -d= -f2)\n\n  # Query MusicBrainz for release MBID\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  album_enc=$(echo \"$album\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:${artist_enc}%20AND%20release:${album_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  mbid=$(echo \"$mbdata\" | jq -r '.releases[0].id')\n\n  # Download cover\n  if curl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"; then\n    # Embed cover\n    opustags -i \"$file\" --set-cover \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n    echo \"Embedded cover: $file\"\n  else\n    echo \"No cover found: $file\"\n  fi\n\n  # Rate limit\n  sleep 1\ndone\n```\n\n## Canonical Artwork Directory\n\nFrom field testing: use a single `artwork\u002F` directory for all artwork files, not scattered copies.\n\n### Directory Structure\n\n```\nartwork\u002F\n├── albums\u002F\n│   ├── blue.jpg\n│   ├── court-and-spark.jpg\n│   ├── hejira.jpg\n│   └── clouds.jpg\n├── artists\u002F\n│   ├── joni-mitchell-1970.jpg\n│   ├── joni-mitchell-1976.jpg\n│   └── joni-mitchell-2000.jpg\n├── live\u002F\n│   ├── isle-of-wight-1970.jpg\n│   └── carnegie-hall-1969.jpg\n├── logos\u002F\n│   └── joni-mitchell-logo.png\n├── promotional\u002F\n│   ├── blue-era-promo.jpg\n│   └── court-and-spark-promo.jpg\n└── ATTRIBUTION.md\n```\n\n### Populate Artwork Directory\n\n```bash\n# Create structure\nmkdir -p artwork\u002F{albums,artists,live,logos,promotional}\n\n# Download album covers\ncd artwork\u002Falbums\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o blue.jpg\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o court-and-spark.jpg\n\n# Download artist images from fanart.tv\ncd ..\u002Fartists\ncurl -s \"https:\u002F\u002Ffanart.tv\u002F...\" -o joni-mitchell-1970.jpg\n\n# Extract video thumbnails\ncd ..\u002Flive\nffmpeg -i ..\u002F..\u002Fvideo\u002Fisle-of-wight-1970.mp4 -ss 00:01:30 -frames:v 1 -q:v 2 isle-of-wight-1970.jpg\n```\n\n### Embed from Canonical Directory\n\n```bash\n# Reference artwork by path\nfor file in music\u002FJoni\\ Mitchell\u002FBlue\u002F*.opus; do\n  opustags -i \"$file\" --set-cover artwork\u002Falbums\u002Fblue.jpg\ndone\n\n# Or create symlink in album directory\nln -s ..\u002F..\u002Fartwork\u002Falbums\u002Fblue.jpg music\u002FJoni\\ Mitchell\u002FBlue\u002Fcover.jpg\n```\n\n### ATTRIBUTION.md\n\nRecord source and rights for all artwork:\n\n```markdown\n# Artwork Attribution\n\n## Albums\n\n### blue.jpg\n- Source: MusicBrainz Cover Art Archive\n- URL: https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F5c004fe3-6e96-3f43-9a85-16e5be8805fa\n- License: Public Domain\n- Uploaded by: user123\n- Date: 2015-03-20\n\n### court-and-spark.jpg\n- Source: fanart.tv\n- URL: https:\u002F\u002Ffanart.tv\u002Fmusic\u002F...\n- License: Fair Use\n- Date: 2018-07-15\n\n## Artists\n\n### joni-mitchell-1970.jpg\n- Source: Extracted from \"Live at Isle of Wight 1970\" video\n- License: Fair Use\n- Date: 2026-02-14\n\n## Live\n\n### isle-of-wight-1970.jpg\n- Source: Video frame extraction (ffmpeg)\n- Original video: Live at Isle of Wight 1970.mp4\n- License: Fair Use\n- Date: 2026-02-14\n```\n\n## Extract Embedded Artwork\n\n### From Opus Files\n\n```bash\n# opustags does not support extraction, use ffmpeg\nffmpeg -i input.opus -an -vcodec copy cover.jpg\n```\n\n### From MP4 Files\n\n```bash\n# Extract first attached picture\nffmpeg -i input.mp4 -map 0:v -map -0:V -c copy cover.jpg\n\n# Extract all video streams (including artwork)\nffmpeg -i input.mp4 -map 0:v -c copy \"stream-%d.jpg\"\n```\n\n### From MP3 Files\n\n```bash\n# Extract cover art\nffmpeg -i input.mp3 -an -vcodec copy cover.jpg\n\n# Using id3v2 (alternative)\nid3v2 -l input.mp3  # List frames\nid3v2 --APIC input.mp3 > cover.jpg  # Extract\n```\n\n### From FLAC Files\n\n```bash\n# Extract using metaflac\nmetaflac --export-picture-to=cover.jpg input.flac\n\n# Or ffmpeg\nffmpeg -i input.flac -an -vcodec copy cover.jpg\n```\n\n## Quality Checks\n\n### Verify Artwork is Embedded\n\n```bash\n# Opus\nopustags input.opus | grep -i picture\n\n# MP4\nffprobe -v error -select_streams v -show_entries stream=disposition:stream_tags input.mp4\n\n# MP3\nffprobe -v error -show_entries format_tags input.mp3 | grep -i picture\n\n# Or extract and check file size\nffmpeg -i input.mp3 -an -vcodec copy test.jpg\nls -lh test.jpg  # Should be >50KB for quality cover\n```\n\n### Check Image Dimensions\n\n```bash\n# Using identify (ImageMagick)\nidentify cover.jpg\n\n# Using ffprobe\nffprobe -v error -select_streams v:0 -show_entries stream=width,height cover.jpg\n```\n\n### Verify File Size\n\n```bash\n# Check cover file size\nls -lh cover.jpg\n\n# Ideal: 100KB - 500KB\n# Too small (\u003C50KB): low quality\n# Too large (>1MB): unnecessary bloat\n```\n\n## Troubleshooting\n\n### Cover Not Displaying in Media Player\n\n```bash\n# Check if cover is actually embedded\nffprobe -v error -show_entries format_tags input.mp3\n\n# Re-embed with correct disposition\nffmpeg -i input.mp4 -i cover.jpg -map 0 -map 1 -c copy \\\n  -disposition:v:1 attached_pic \\\n  output.mp4\n```\n\n### Image Format Not Supported\n\n```bash\n# Convert to JPEG\nconvert input.png output.jpg\n\n# Re-embed converted image\nopustags -i input.opus --set-cover output.jpg\n```\n\n### Image Too Large (Slow Loading)\n\n```bash\n# Resize and optimize\nconvert cover.jpg -resize 1200x1200 -quality 85 cover-optimized.jpg\n\n# Re-embed optimized image\nopustags -i input.opus --set-cover cover-optimized.jpg\n```\n\n### MusicBrainz Cover Not Available\n\n```bash\n# Try fanart.tv\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url'\n\n# Or Google Images (manual)\n# Or extract from video if available\n```\n\n## Complete Workflow Example\n\n```bash\n#!\u002Fbin\u002Fbash\n# Download cover from MusicBrainz, process, and embed\n\nfile=\"$1\"\n\n# Get album MBID from existing tags\nalbum=$(opustags \"$file\" | grep \"ALBUM=\" | cut -d= -f2)\nartist=$(opustags \"$file\" | grep \"ARTIST=\" | cut -d= -f2)\n\n# Query MusicBrainz\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\nalbum_enc=$(echo \"$album\" | jq -sRr @uri)\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:${artist_enc}%20AND%20release:${album_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\")\n\nmbid=$(echo \"$mbdata\" | jq -r '.releases[0].id')\n\n# Download cover\ncover_url=\"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\"\ncurl -s \"$cover_url\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\n# Process: resize, optimize, strip metadata\nconvert \"\u002Ftmp\u002Fcover-${mbid}.jpg\" \\\n  -resize 1200x1200 \\\n  -quality 85 \\\n  -strip \\\n  \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\"\n\n# Embed into file\nopustags -i \"$file\" --set-cover \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\"\n\n# Save to canonical directory\nartist_safe=$(echo \"$artist\" | tr '\u002F' '-')\nalbum_safe=$(echo \"$album\" | tr '\u002F' '-')\nmkdir -p \"artwork\u002Falbums\"\ncp \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\" \"artwork\u002Falbums\u002F${artist_safe}-${album_safe}.jpg\"\n\n# Update ATTRIBUTION.md\ncat >> artwork\u002FATTRIBUTION.md \u003C\u003CEOF\n\n### ${artist_safe}-${album_safe}.jpg\n- Source: MusicBrainz Cover Art Archive\n- URL: ${cover_url}\n- MBID: ${mbid}\n- Date: $(date +%Y-%m-%d)\nEOF\n\necho \"Cover embedded: $file\"\necho \"Saved to: artwork\u002Falbums\u002F${artist_safe}-${album_safe}.jpg\"\n```\n\n## See Also\n\n- Command: `\u002Ftag-collection`\n- Skill: `@metadata-tagging`\n- Agent: `@Metadata Curator`\n- MusicBrainz CAA: https:\u002F\u002Fcoverartarchive.org\u002F\n- fanart.tv API: https:\u002F\u002Ffanart.tv\u002Fapi-docs\u002F\n- ImageMagick documentation: https:\u002F\u002Fimagemagick.org\u002F\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before overwriting existing embedded artwork\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fmetadata-tagging\u002FSKILL.md — Metadata tagging skill used alongside cover art embedding for complete file tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Ftag-collection\u002FSKILL.md — Tag collection skill that orchestrates metadata and artwork embedding together\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fintegrity-verification\u002FSKILL.md — Verify file integrity after embedding artwork\n","# Cover Art Embedding Skill\n\nConcrete patterns for finding high-quality cover artwork, processing it for optimal size and format, and embedding it into audio and video files.\n\n## Artwork Sources\n\n### MusicBrainz Cover Art Archive (Primary)\n\nMusicBrainz Cover Art Archive (CAA) is the authoritative source for album artwork.\n\n**Get Front Cover by Release MBID**:\n```bash\n# Download front cover for a release\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o cover.jpg\n\n# Example with real MBID\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F5c004fe3-6e96-3f43-9a85-16e5be8805fa\u002Ffront\" -o blue-cover.jpg\n```\n\n**Check if Cover Exists**:\n```bash\n# HEAD request to check without downloading\nif curl -s -I \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" | grep -q \"200 OK\"; then\n  echo \"Cover available\"\nelse\n  echo \"No cover found\"\nfi\n```\n\n**Get All Available Images**:\n```bash\n# Get metadata for all images\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | jq .\n\n# Extract URLs for all front covers\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | \\\n  jq -r '.images[] | select(.front == true) | .image'\n\n# Download highest resolution front cover\nurl=$(curl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\" | \\\n  jq -r '.images[] | select(.front == true) | .image' | head -1)\ncurl -s \"$url\" -o cover.jpg\n```\n\n### fanart.tv API\n\nfanart.tv provides high-quality artist images, album covers, and logos.\n\n**Get Artist Images**:\n```bash\n# Requires API key from https:\u002F\u002Ffanart.tv\u002Fget-an-api-key\u002F\nFANART_API_KEY=\"your-api-key\"\n\n# Get all artist artwork\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\"\n\n# Extract album cover URLs\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url'\n\n# Extract artist background\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.artistbackground[0].url'\n\n# Extract artist logo\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.hdmusiclogo[0].url'\n```\n\n**Download Artwork**:\n```bash\n# Download album cover\nurl=$(curl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url')\ncurl -s \"$url\" -o cover.jpg\n```\n\n### Video Thumbnail Extraction\n\nExtract cover artwork from video frames.\n\n**Using yt-dlp** (if video was downloaded with thumbnail):\n```bash\n# Download video with thumbnail\nyt-dlp --write-thumbnail --convert-thumbnails jpg \"https:\u002F\u002Fyoutube.com\u002Fwatch?v=...\"\n\n# Result: video.jpg alongside video.mp4\n```\n\n**Using ffmpeg** (extract from video):\n```bash\n# Extract single frame at specific time\nffmpeg -i input.mp4 -ss 00:00:10 -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract I-frame (best quality)\nffmpeg -i input.mp4 -vf \"select=eq(pict_type\\,I)\" -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract frame at 25% into video\nduration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4)\ntimestamp=$(echo \"$duration * 0.25\" | bc)\nffmpeg -i input.mp4 -ss \"$timestamp\" -frames:v 1 -q:v 2 thumbnail.jpg\n\n# Extract highest quality frame from first minute\nffmpeg -i input.mp4 -t 60 -vf \"select=eq(pict_type\\,I)\" -vsync vfr -q:v 1 frames-%03d.jpg\n# Then manually select best frame\n```\n\n### Local Artwork Files\n\nScan for existing artwork in standard locations:\n\n```bash\n# Check for common filenames in album directory\nfor name in cover.jpg Cover.jpg folder.jpg Folder.jpg albumart.jpg AlbumArt.jpg; do\n  if [ -f \"$name\" ]; then\n    echo \"Found: $name\"\n    break\n  fi\ndone\n\n# Search parent directory\nif [ -f \"..\u002Fcover.jpg\" ]; then\n  cp \"..\u002Fcover.jpg\" .\nfi\n\n# Find largest image file (likely the cover)\nlargest=$(find . -maxdepth 1 -type f \\( -iname \"*.jpg\" -o -iname \"*.png\" \\) -exec ls -s {} \\; | \\\n  sort -rn | head -1 | awk '{print $2}')\necho \"Largest image: $largest\"\n```\n\n## Image Processing\n\n### Resize for Mobile Optimization\n\nReduce image size for faster loading and smaller file sizes:\n\n```bash\n# Install ImageMagick\nbrew install imagemagick  # macOS\nsudo apt install imagemagick  # Debian\u002FUbuntu\n\n# Resize to 1200x1200 max (preserves aspect ratio)\nconvert input.jpg -resize 1200x1200 output.jpg\n\n# Resize and optimize quality (85% JPEG quality)\nconvert input.jpg -resize 1200x1200 -quality 85 output.jpg\n\n# Create thumbnail (300x300)\nconvert input.jpg -resize 300x300 thumbnail.jpg\n\n# Batch resize all images in directory\nfor img in *.jpg; do\n  convert \"$img\" -resize 1200x1200 -quality 85 \"${img%.jpg}-resized.jpg\"\ndone\n```\n\n### Format Conversion\n\nConvert between image formats:\n\n```bash\n# PNG to JPEG\nconvert input.png output.jpg\n\n# WebP to JPEG\nconvert input.webp output.jpg\n\n# JPEG to PNG (lossless)\nconvert input.jpg output.png\n\n# Batch convert all PNG to JPEG\nfor img in *.png; do\n  convert \"$img\" \"${img%.png}.jpg\"\ndone\n```\n\n### Crop to Square\n\nCrop non-square images to square aspect ratio:\n\n```bash\n# Center crop to square\nconvert input.jpg -gravity center -crop 1:1 +repage output.jpg\n\n# Crop from top-left\nconvert input.jpg -crop 1200x1200+0+0 +repage output.jpg\n\n# Smart crop (removes boring edges)\nconvert input.jpg -define trim:percent-background=0% -trim +repage -resize 1200x1200 output.jpg\n```\n\n### Remove Metadata (Privacy)\n\nStrip EXIF data before embedding:\n\n```bash\n# Remove all metadata\nconvert input.jpg -strip output.jpg\n\n# Or use exiftool\nexiftool -all= input.jpg\n\n# Batch strip metadata\nfor img in *.jpg; do\n  convert \"$img\" -strip \"${img%.jpg}-clean.jpg\"\ndone\n```\n\n## Embedding Artwork\n\n### Opus Files (opustags)\n\n```bash\n# Embed cover art from JPEG file\nopustags input.opus --set-cover cover.jpg -o output.opus\n\n# In-place embedding\nopustags -i input.opus --set-cover cover.jpg\n\n# Verify embedding\nopustags input.opus | grep -i picture\n```\n\n### MP4 Files (ffmpeg)\n\n```bash\n# Embed cover as attached picture\nffmpeg -i input.mp4 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:1 attached_pic \\\n  output.mp4\n\n# Embed with metadata\nffmpeg -i input.mp4 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:1 attached_pic \\\n  -metadata:s:v:1 title=\"Album cover\" \\\n  -metadata:s:v:1 comment=\"Cover (front)\" \\\n  output.mp4\n\n# Verify embedding\nffprobe -v error -select_streams v -show_entries stream=codec_name,codec_type,disposition input.mp4\n```\n\n### MP3 Files (ffmpeg)\n\n```bash\n# Embed cover with ID3v2.3\nffmpeg -i input.mp3 -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -id3v2_version 3 \\\n  -metadata:s:v title=\"Album cover\" \\\n  -metadata:s:v comment=\"Cover (front)\" \\\n  output.mp3\n\n# Verify embedding\nffmpeg -i input.mp3 -an -vcodec copy test-extracted-cover.jpg\n```\n\n### FLAC Files (ffmpeg)\n\n```bash\n# Embed cover into FLAC\nffmpeg -i input.flac -i cover.jpg \\\n  -map 0 -map 1 \\\n  -c copy \\\n  -disposition:v:0 attached_pic \\\n  output.flac\n\n# Using metaflac (alternative)\nmetaflac --import-picture-from=cover.jpg input.flac\n```\n\n## Batch Embedding\n\n### Embed Same Cover into All Files\n\n```bash\n# Opus files in directory\nfor file in *.opus; do\n  opustags -i \"$file\" --set-cover cover.jpg\n  echo \"Embedded: $file\"\ndone\n\n# MP3 files in directory\nfor file in *.mp3; do\n  ffmpeg -i \"$file\" -i cover.jpg \\\n    -map 0 -map 1 -c copy \\\n    -id3v2_version 3 \\\n    -metadata:s:v title=\"Album cover\" \\\n    \"${file%.mp3}-covered.mp3\"\n  mv \"${file%.mp3}-covered.mp3\" \"$file\"\ndone\n```\n\n### Embed Different Covers per Album\n\n```bash\n# Process album directories\nfor album_dir in *\u002F; do\n  # Find cover in album directory\n  cover=$(find \"$album_dir\" -maxdepth 1 -iname \"cover.jpg\" | head -1)\n\n  if [ -n \"$cover\" ]; then\n    # Embed into all Opus files in this album\n    for file in \"$album_dir\"\u002F*.opus; do\n      opustags -i \"$file\" --set-cover \"$cover\"\n    done\n    echo \"Processed: $album_dir\"\n  else\n    echo \"No cover found: $album_dir\"\n  fi\ndone\n```\n\n### Download and Embed from MusicBrainz\n\n```bash\n#!\u002Fbin\u002Fbash\n# Process all Opus files, download covers, embed\n\nfor file in *.opus; do\n  # Extract artist and album from tags\n  artist=$(opustags \"$file\" | grep \"ARTIST=\" | cut -d= -f2)\n  album=$(opustags \"$file\" | grep \"ALBUM=\" | cut -d= -f2)\n\n  # Query MusicBrainz for release MBID\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  album_enc=$(echo \"$album\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:${artist_enc}%20AND%20release:${album_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  mbid=$(echo \"$mbdata\" | jq -r '.releases[0].id')\n\n  # Download cover\n  if curl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"; then\n    # Embed cover\n    opustags -i \"$file\" --set-cover \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n    echo \"Embedded cover: $file\"\n  else\n    echo \"No cover found: $file\"\n  fi\n\n  # Rate limit\n  sleep 1\ndone\n```\n\n## Canonical Artwork Directory\n\nFrom field testing: use a single `artwork\u002F` directory for all artwork files, not scattered copies.\n\n### Directory Structure\n\n```\nartwork\u002F\n├── albums\u002F\n│   ├── blue.jpg\n│   ├── court-and-spark.jpg\n│   ├── hejira.jpg\n│   └── clouds.jpg\n├── artists\u002F\n│   ├── joni-mitchell-1970.jpg\n│   ├── joni-mitchell-1976.jpg\n│   └── joni-mitchell-2000.jpg\n├── live\u002F\n│   ├── isle-of-wight-1970.jpg\n│   └── carnegie-hall-1969.jpg\n├── logos\u002F\n│   └── joni-mitchell-logo.png\n├── promotional\u002F\n│   ├── blue-era-promo.jpg\n│   └── court-and-spark-promo.jpg\n└── ATTRIBUTION.md\n```\n\n### Populate Artwork Directory\n\n```bash\n# Create structure\nmkdir -p artwork\u002F{albums,artists,live,logos,promotional}\n\n# Download album covers\ncd artwork\u002Falbums\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o blue.jpg\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F{mbid}\u002Ffront\" -o court-and-spark.jpg\n\n# Download artist images from fanart.tv\ncd ..\u002Fartists\ncurl -s \"https:\u002F\u002Ffanart.tv\u002F...\" -o joni-mitchell-1970.jpg\n\n# Extract video thumbnails\ncd ..\u002Flive\nffmpeg -i ..\u002F..\u002Fvideo\u002Fisle-of-wight-1970.mp4 -ss 00:01:30 -frames:v 1 -q:v 2 isle-of-wight-1970.jpg\n```\n\n### Embed from Canonical Directory\n\n```bash\n# Reference artwork by path\nfor file in music\u002FJoni\\ Mitchell\u002FBlue\u002F*.opus; do\n  opustags -i \"$file\" --set-cover artwork\u002Falbums\u002Fblue.jpg\ndone\n\n# Or create symlink in album directory\nln -s ..\u002F..\u002Fartwork\u002Falbums\u002Fblue.jpg music\u002FJoni\\ Mitchell\u002FBlue\u002Fcover.jpg\n```\n\n### ATTRIBUTION.md\n\nRecord source and rights for all artwork:\n\n```markdown\n# Artwork Attribution\n\n## Albums\n\n### blue.jpg\n- Source: MusicBrainz Cover Art Archive\n- URL: https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F5c004fe3-6e96-3f43-9a85-16e5be8805fa\n- License: Public Domain\n- Uploaded by: user123\n- Date: 2015-03-20\n\n### court-and-spark.jpg\n- Source: fanart.tv\n- URL: https:\u002F\u002Ffanart.tv\u002Fmusic\u002F...\n- License: Fair Use\n- Date: 2018-07-15\n\n## Artists\n\n### joni-mitchell-1970.jpg\n- Source: Extracted from \"Live at Isle of Wight 1970\" video\n- License: Fair Use\n- Date: 2026-02-14\n\n## Live\n\n### isle-of-wight-1970.jpg\n- Source: Video frame extraction (ffmpeg)\n- Original video: Live at Isle of Wight 1970.mp4\n- License: Fair Use\n- Date: 2026-02-14\n```\n\n## Extract Embedded Artwork\n\n### From Opus Files\n\n```bash\n# opustags does not support extraction, use ffmpeg\nffmpeg -i input.opus -an -vcodec copy cover.jpg\n```\n\n### From MP4 Files\n\n```bash\n# Extract first attached picture\nffmpeg -i input.mp4 -map 0:v -map -0:V -c copy cover.jpg\n\n# Extract all video streams (including artwork)\nffmpeg -i input.mp4 -map 0:v -c copy \"stream-%d.jpg\"\n```\n\n### From MP3 Files\n\n```bash\n# Extract cover art\nffmpeg -i input.mp3 -an -vcodec copy cover.jpg\n\n# Using id3v2 (alternative)\nid3v2 -l input.mp3  # List frames\nid3v2 --APIC input.mp3 > cover.jpg  # Extract\n```\n\n### From FLAC Files\n\n```bash\n# Extract using metaflac\nmetaflac --export-picture-to=cover.jpg input.flac\n\n# Or ffmpeg\nffmpeg -i input.flac -an -vcodec copy cover.jpg\n```\n\n## Quality Checks\n\n### Verify Artwork is Embedded\n\n```bash\n# Opus\nopustags input.opus | grep -i picture\n\n# MP4\nffprobe -v error -select_streams v -show_entries stream=disposition:stream_tags input.mp4\n\n# MP3\nffprobe -v error -show_entries format_tags input.mp3 | grep -i picture\n\n# Or extract and check file size\nffmpeg -i input.mp3 -an -vcodec copy test.jpg\nls -lh test.jpg  # Should be >50KB for quality cover\n```\n\n### Check Image Dimensions\n\n```bash\n# Using identify (ImageMagick)\nidentify cover.jpg\n\n# Using ffprobe\nffprobe -v error -select_streams v:0 -show_entries stream=width,height cover.jpg\n```\n\n### Verify File Size\n\n```bash\n# Check cover file size\nls -lh cover.jpg\n\n# Ideal: 100KB - 500KB\n# Too small (\u003C50KB): low quality\n# Too large (>1MB): unnecessary bloat\n```\n\n## Troubleshooting\n\n### Cover Not Displaying in Media Player\n\n```bash\n# Check if cover is actually embedded\nffprobe -v error -show_entries format_tags input.mp3\n\n# Re-embed with correct disposition\nffmpeg -i input.mp4 -i cover.jpg -map 0 -map 1 -c copy \\\n  -disposition:v:1 attached_pic \\\n  output.mp4\n```\n\n### Image Format Not Supported\n\n```bash\n# Convert to JPEG\nconvert input.png output.jpg\n\n# Re-embed converted image\nopustags -i input.opus --set-cover output.jpg\n```\n\n### Image Too Large (Slow Loading)\n\n```bash\n# Resize and optimize\nconvert cover.jpg -resize 1200x1200 -quality 85 cover-optimized.jpg\n\n# Re-embed optimized image\nopustags -i input.opus --set-cover cover-optimized.jpg\n```\n\n### MusicBrainz Cover Not Available\n\n```bash\n# Try fanart.tv\ncurl -s \"https:\u002F\u002Fwebservice.fanart.tv\u002Fv3\u002Fmusic\u002F${mbid}?api_key=${FANART_API_KEY}\" | \\\n  jq -r '.albums.\"'\"$album_mbid\"'\".albumcover[0].url'\n\n# Or Google Images (manual)\n# Or extract from video if available\n```\n\n## Complete Workflow Example\n\n```bash\n#!\u002Fbin\u002Fbash\n# Download cover from MusicBrainz, process, and embed\n\nfile=\"$1\"\n\n# Get album MBID from existing tags\nalbum=$(opustags \"$file\" | grep \"ALBUM=\" | cut -d= -f2)\nartist=$(opustags \"$file\" | grep \"ARTIST=\" | cut -d= -f2)\n\n# Query MusicBrainz\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\nalbum_enc=$(echo \"$album\" | jq -sRr @uri)\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:${artist_enc}%20AND%20release:${album_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\")\n\nmbid=$(echo \"$mbdata\" | jq -r '.releases[0].id')\n\n# Download cover\ncover_url=\"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\"\ncurl -s \"$cover_url\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\n# Process: resize, optimize, strip metadata\nconvert \"\u002Ftmp\u002Fcover-${mbid}.jpg\" \\\n  -resize 1200x1200 \\\n  -quality 85 \\\n  -strip \\\n  \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\"\n\n# Embed into file\nopustags -i \"$file\" --set-cover \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\"\n\n# Save to canonical directory\nartist_safe=$(echo \"$artist\" | tr '\u002F' '-')\nalbum_safe=$(echo \"$album\" | tr '\u002F' '-')\nmkdir -p \"artwork\u002Falbums\"\ncp \"\u002Ftmp\u002Fcover-${mbid}-processed.jpg\" \"artwork\u002Falbums\u002F${artist_safe}-${album_safe}.jpg\"\n\n# Update ATTRIBUTION.md\ncat >> artwork\u002FATTRIBUTION.md \u003C\u003CEOF\n\n### ${artist_safe}-${album_safe}.jpg\n- Source: MusicBrainz Cover Art Archive\n- URL: ${cover_url}\n- MBID: ${mbid}\n- Date: $(date +%Y-%m-%d)\nEOF\n\necho \"Cover embedded: $file\"\necho \"Saved to: artwork\u002Falbums\u002F${artist_safe}-${album_safe}.jpg\"\n```\n\n## See Also\n\n- Command: `\u002Ftag-collection`\n- Skill: `@metadata-tagging`\n- Agent: `@Metadata Curator`\n- MusicBrainz CAA: https:\u002F\u002Fcoverartarchive.org\u002F\n- fanart.tv API: https:\u002F\u002Ffanart.tv\u002Fapi-docs\u002F\n- ImageMagick documentation: https:\u002F\u002Fimagemagick.org\u002F\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before overwriting existing embedded artwork\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fmetadata-tagging\u002FSKILL.md — Metadata tagging skill used alongside cover art embedding for complete file tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Ftag-collection\u002FSKILL.md — Tag collection skill that orchestrates metadata and artwork embedding together\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fintegrity-verification\u002FSKILL.md — Verify file integrity after embedding artwork\n",{"name":5,"category":44,"namespace":45,"platforms":46,"description":7},"media-curator","aiwg",[47],"all","main","6754967c344ccb087a8de06972f55a41067b291b","agentic\u002Fcode\u002Fplugins\u002Fmedia-curator\u002Fskills\u002Fcover-art-embedding",36,"https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg","https:\u002F\u002Faiwg.io","https:\u002F\u002Fgithub.com\u002Fjmagly","https:\u002F\u002Fintegrolabs.io","ml\u002Fai, industrial automation, safety\u002Fsecurity, ssi\r\n\r\nmagly.net\r\nintegrolabs.io\r\naiwg.io\r\nfortemi.com\r\npagenary.com\r\nbytecask.com","2026-11-12 21:57:33",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":70},[60,63,66],{"tool":61,"command":62},"npx","npx skills add jmagly\u002Faiwg --skill cover-art-embedding",{"tool":64,"command":65},"bunx","bunx skills add jmagly\u002Faiwg --skill cover-art-embedding",{"tool":67,"command":68},"pnpm","pnpm dlx skills add jmagly\u002Faiwg --skill cover-art-embedding","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fmedia-curator\u002Fskills\u002Fcover-art-embedding\u002FSKILL.md",true,[],[73,101,125,131,138,152],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":80,"publishedAt":39},"01M70QA0BSYJ49EES9V4RE8QH1","host-hardening","Read-only system hardening baseline and plan-first host hardening recommendations for SSH, Docker bind addresses, firewall persistence, datastores, exporters and audit retention.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[79],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100],"host","host hardening","hardening","read","re","recommendations","remediation","plan","port","verification","Bash","access","only","retention","audit","never","firewall","bind","secrets","request",{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":111,"publishedAt":39},"01M70PNT2Z4HMZPRBTAF6073NN","exposure-analysis","Read-only firewall analysis and effective host exposure reconstruction for Docker published ports, UFW bypass, stale rules, CDN scope, IPv6 asymmetry and external probe allowlists.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fforensics\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[107,110],{"categoryNo":108,"categoryName":109,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[112,113,114,84,115,89,116,117,91,118,81,119,93,120,121,96,97,122,123,124],"exposure analysis","analysis","unknown","credentials","collection","ufw","ports","internet","local","scope","reconstruction","operator","write",{"skillNo":126,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":130,"publishedAt":39},"01M70P8QATMPKA78E4FT5D2TNA","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[129],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[83,81,82,92,84,100,87,86,95,88,89,90,91,99,93,94,85,96,97,98],{"skillNo":132,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":137,"publishedAt":39},"01M70NMPVJ5H0JH131P60FW4R8","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fforensics-complete\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[135,136],{"categoryNo":108,"categoryName":109,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[113,112,96,115,89,116,91,114,81,119,93,120,121,84,97,118,117,122,123,124],{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":145,"publishedAt":39},"01M6CB4DDR0B4NNCFK7ZK7449H","fixture-skill","Exercise rule delivery.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Frule-delivery\u002Fskills\u002Ffixture-skill\u002FSKILL.md",[144],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[146,147,148,149,150,151],"fixture skill","fixture","rule","delivery","true","exercise",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":156,"categories":157,"keywords":159,"publishedAt":39},"01M6CB4AVK1W76MFMPP0JP32CJ","pi-local","Pi-local duplicate-precedence fixture.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fproviders\u002Fpi\u002Fproject\u002F.pi\u002Fskills\u002Fpi-local\u002FSKILL.md",[158],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[160,161,120,162,147],"pi","pi local","duplicate"]