[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C3749T0JFFTA044P08EZFD":3,"skill-same:01M6C3749T0JFFTA044P08EZFD":70},{"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":26,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":46,"commitSha":47,"skillDirectory":48,"forksCount":49,"repositoryHtmlUrl":50,"repositoryHomepageUrl":51,"ownerHtmlUrl":52,"ownerBlogUrl":53,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M6C3749T0JFFTA044P08EZFD","metadata-tagging",null,"opustags and ffmpeg patterns for applying metadata to audio and video 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\u002Fmetadata-tagging\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36],"metadata","metadata tagging","tagging","Video","Media","Audio","files","patterns","ffmpeg","for","2026-11-10 10:12:30",false,"---\nnamespace: aiwg\nplatforms: [all]\nname: metadata-tagging\ndescription: opustags and ffmpeg patterns for applying metadata to audio and video files\ncategory: media-curator\n---\n\n# Metadata Tagging Skill\n\nConcrete patterns for applying metadata tags to audio and video files using opustags (Opus) and ffmpeg (MP4\u002FMP3\u002FFLAC).\n\n## opustags (Opus Files)\n\n### Install\n\n```bash\n# macOS\nbrew install opustags\n\n# Ubuntu\u002FDebian\nsudo apt install opustags\n\n# Arch\nsudo pacman -S opustags\n\n# From source\ngit clone https:\u002F\u002Fgithub.com\u002Ffmang\u002Fopustags.git\ncd opustags\ncmake -S . -B build\ncmake --build build\nsudo cmake --install build\n```\n\n### Set Basic Tags\n\n```bash\n# Set all common tags at once\nopustags input.opus \\\n  --set \"TITLE=Both Sides Now\" \\\n  --set \"ARTIST=Joni Mitchell\" \\\n  --set \"ALBUM=Clouds\" \\\n  --set \"ALBUMARTIST=Joni Mitchell\" \\\n  --set \"TRACKNUMBER=12\" \\\n  --set \"DATE=1969\" \\\n  --set \"GENRE=Folk\" \\\n  -o output.opus\n```\n\n### Set Individual Tags\n\n```bash\n# Title\nopustags input.opus --set \"TITLE=Song Title\" -o output.opus\n\n# Artist\nopustags input.opus --set \"ARTIST=Artist Name\" -o output.opus\n\n# Album\nopustags input.opus --set \"ALBUM=Album Name\" -o output.opus\n\n# Album Artist (for compilations)\nopustags input.opus --set \"ALBUMARTIST=Various Artists\" -o output.opus\n\n# Track number\nopustags input.opus --set \"TRACKNUMBER=3\" -o output.opus\n\n# Track number with total\nopustags input.opus --set \"TRACKNUMBER=3\u002F12\" -o output.opus\n\n# Year\nopustags input.opus --set \"DATE=1969\" -o output.opus\n\n# Genre\nopustags input.opus --set \"GENRE=Folk Rock\" -o output.opus\n\n# Comment\nopustags input.opus --set \"COMMENT=Live at Carnegie Hall\" -o output.opus\n```\n\n### In-Place Updates\n\n```bash\n# Modify file in place (overwrites original)\nopustags -i input.opus --set \"TITLE=New Title\"\n\n# Multiple tags in-place\nopustags -i input.opus \\\n  --set \"TITLE=New Title\" \\\n  --set \"ARTIST=New Artist\"\n```\n\n### Read Tags\n\n```bash\n# Display all tags\nopustags input.opus\n\n# Save tags to file\nopustags input.opus > tags.txt\n\n# Check if specific tag exists\nopustags input.opus | grep \"TITLE=\"\n```\n\n### Delete Tags\n\n```bash\n# Delete specific tag\nopustags input.opus --delete \"COMMENT\" -o output.opus\n\n# Delete all tags (keep only vendor string)\nopustags input.opus --delete-all -o output.opus\n```\n\n### Set Cover Art\n\n```bash\n# Embed cover from JPEG file\nopustags input.opus --set-cover cover.jpg -o output.opus\n\n# In-place cover embedding\nopustags -i input.opus --set-cover cover.jpg\n\n# Replace existing cover\nopustags -i input.opus --set-cover new-cover.jpg\n```\n\n### Batch Operations\n\n```bash\n# Set same tags on all files in directory\nfor file in *.opus; do\n  opustags -i \"$file\" \\\n    --set \"ALBUMARTIST=Joni Mitchell\" \\\n    --set \"ALBUM=Blue\" \\\n    --set \"DATE=1971\"\ndone\n\n# Embed same cover into all files\nfor file in *.opus; do\n  opustags -i \"$file\" --set-cover ..\u002Fcover.jpg\ndone\n\n# Set track numbers sequentially\ntrack=1\nfor file in *.opus; do\n  opustags -i \"$file\" --set \"TRACKNUMBER=$track\"\n  ((track++))\ndone\n```\n\n### Extract Cover Art\n\n```bash\n# Extract cover to file (requires parsing output)\nopustags input.opus | grep -A 1000 \"METADATA_BLOCK_PICTURE\" > cover-encoded.txt\n\n# Note: opustags does not have built-in cover extraction\n# Use ffmpeg for this instead (see below)\n```\n\n## ffmpeg (MP4\u002FMP3\u002FFLAC)\n\n### Set MP4 Metadata\n\n```bash\n# Set all common tags\nffmpeg -i input.mp4 -c copy \\\n  -metadata title=\"Both Sides Now\" \\\n  -metadata artist=\"Joni Mitchell\" \\\n  -metadata album=\"Live at Isle of Wight 1970\" \\\n  -metadata date=\"1970\" \\\n  -metadata genre=\"Folk\" \\\n  -metadata comment=\"Restored from VHS\" \\\n  output.mp4\n```\n\n### Set MP3 Metadata (ID3v2.3)\n\n```bash\n# Set tags with ID3v2.3 for compatibility\nffmpeg -i input.mp3 -c copy \\\n  -id3v2_version 3 \\\n  -metadata title=\"Both Sides Now\" \\\n  -metadata artist=\"Joni Mitchell\" \\\n  -metadata album=\"Clouds\" \\\n  -metadata date=\"1969\" \\\n  -metadata track=\"12\u002F14\" \\\n  -metadata genre=\"Folk\" \\\n  output.mp3\n```\n\n### Set FLAC Metadata (Vorbis Comments)\n\n```bash\n# FLAC uses Vorbis comments like Opus\nffmpeg -i input.flac -c copy \\\n  -metadata TITLE=\"Both Sides Now\" \\\n  -metadata ARTIST=\"Joni Mitchell\" \\\n  -metadata ALBUM=\"Clouds\" \\\n  -metadata DATE=\"1969\" \\\n  -metadata TRACKNUMBER=\"12\" \\\n  output.flac\n```\n\n### Embed Cover Art into MP4\n\n```bash\n# Add 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\n### Embed Cover Art into MP3\n\n```bash\n# Add cover with proper ID3v2.3 tags\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\n### Embed Cover Art into FLAC\n\n```bash\n# Add cover to FLAC file\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\n### Extract Cover Art from Any File\n\n```bash\n# Extract first attached picture\nffmpeg -i input.mp3 -an -vcodec copy cover.jpg\n\n# Extract from MP4\nffmpeg -i input.mp4 -map 0:v -map -0:V -c copy cover.jpg\n\n# Extract and convert to PNG\nffmpeg -i input.flac -an -vcodec png cover.png\n```\n\n### Read Metadata\n\n```bash\n# Show all metadata\nffprobe -v quiet -show_format -show_entries format_tags input.mp4\n\n# Show only specific tags\nffprobe -v quiet -show_entries format_tags=title,artist,album input.mp3\n\n# JSON output for parsing\nffprobe -v quiet -print_format json -show_format input.mp4\n```\n\n### Batch MP4 Tagging\n\n```bash\n# Set album and year on all MP4 files\nfor file in *.mp4; do\n  ffmpeg -i \"$file\" -c copy \\\n    -metadata album=\"Live Performances 1970\" \\\n    -metadata date=\"1970\" \\\n    \"${file%.mp4}-tagged.mp4\"\n  mv \"${file%.mp4}-tagged.mp4\" \"$file\"\ndone\n```\n\n## MusicBrainz Lookup\n\n### Recording Search by Artist and Title\n\n```bash\n# Basic search\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:Joni%20Mitchell%20AND%20recording:Both%20Sides%20Now&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0 (contact@example.com)\"\n\n# URL-encode query parameters\nartist=\"Joni Mitchell\"\ntitle=\"Both Sides Now\"\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\ntitle_enc=$(echo \"$title\" | jq -sRr @uri)\n\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Release (Album) Search\n\n```bash\n# Search for release by artist and album\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:Joni%20Mitchell%20AND%20release:Blue&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n\n# Include release group info\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:Joni%20Mitchell%20AND%20release:Blue&inc=release-groups&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Extract Metadata from JSON Response\n\n```bash\n# Get release from recording search\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:Joni%20Mitchell%20AND%20recording:Both%20Sides%20Now&fmt=json\" -H \"User-Agent: MediaCurator\u002F1.0\")\n\n# Extract fields with jq\nalbum=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\nyear=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\nmbid=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].id')\ntrack_num=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].media[0].tracks | map(select(.title == \"Both Sides Now\"))[0].position')\n\necho \"Album: $album\"\necho \"Year: $year\"\necho \"MBID: $mbid\"\necho \"Track: $track_num\"\n```\n\n### Rate Limiting\n\nMusicBrainz allows 1 request per second:\n\n```bash\n# Process multiple files with rate limiting\nfor file in *.opus; do\n  # Extract metadata from filename\n  artist=$(echo \"$file\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\n  title=$(echo \"$file\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n  # Query MusicBrainz\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  title_enc=$(echo \"$title\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  # Extract and apply metadata\n  album=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\n  year=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\n\n  opustags -i \"$file\" \\\n    --set \"ALBUM=$album\" \\\n    --set \"DATE=$year\"\n\n  # Rate limit: wait 1 second\n  sleep 1\ndone\n```\n\n## Filename Parsing Patterns\n\n### Common Patterns\n\n```bash\n# Pattern: \"Artist - Title.ext\"\nartist=$(echo \"$filename\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Artist - Album - Track# - Title.ext\"\nartist=$(echo \"$filename\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\nalbum=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - ([^-]+) - .*\u002F\\1\u002F' | xargs)\ntrack=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - [^-]+ - ([0-9]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - [^-]+ - [^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Track# - Title.ext\" (when artist known)\ntrack=$(echo \"$filename\" | sed -E 's\u002F^([0-9]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[0-9]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Title [Quality].ext\" (video)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^(.+) \\[[^]]+\\]\\..*\u002F\\1\u002F' | xargs)\nquality=$(echo \"$filename\" | sed -E 's\u002F.*\\[([^]]+)\\]\\..*\u002F\\1\u002F' | xargs)\n```\n\n### Clean Extracted Strings\n\n```bash\n# Remove leading\u002Ftrailing whitespace\nartist=$(echo \"$artist\" | xargs)\n\n# Remove underscores, convert to spaces\ntitle=$(echo \"$title\" | tr '_' ' ')\n\n# Capitalize first letter of each word\ntitle=$(echo \"$title\" | sed 's\u002F\\b\\(.\\)\u002F\\u\\1\u002Fg')\n```\n\n## Complete Tagging Workflow\n\n### Single File (Opus)\n\n```bash\n#!\u002Fbin\u002Fbash\nfile=\"$1\"\n\n# Extract metadata from filename\nartist=$(echo \"$file\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$file\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Query MusicBrainz\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\ntitle_enc=$(echo \"$title\" | jq -sRr @uri)\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\")\n\n# Extract metadata\nalbum=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\nyear=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\nmbid=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].id')\ngenre=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0][\"release-group\"][\"primary-type\"]')\n\n# Download cover art\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\n# Apply tags\nopustags -i \"$file\" \\\n  --set \"TITLE=$title\" \\\n  --set \"ARTIST=$artist\" \\\n  --set \"ALBUM=$album\" \\\n  --set \"ALBUMARTIST=$artist\" \\\n  --set \"DATE=$year\" \\\n  --set \"GENRE=$genre\" \\\n  --set-cover \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\necho \"Tagged: $file\"\n```\n\n### Batch Directory (MP4)\n\n```bash\n#!\u002Fbin\u002Fbash\ndir=\"$1\"\nartist=\"$2\"\n\n# Process all MP4 files\nfor file in \"$dir\"\u002F*.mp4; do\n  # Extract title from filename\n  title=$(basename \"$file\" .mp4)\n\n  # Query MusicBrainz\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  title_enc=$(echo \"$title\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  # Extract metadata\n  album=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\n  year=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\n\n  # Apply tags\n  ffmpeg -i \"$file\" -c copy \\\n    -metadata title=\"$title\" \\\n    -metadata artist=\"$artist\" \\\n    -metadata album=\"$album\" \\\n    -metadata date=\"$year\" \\\n    \"${file%.mp4}-tagged.mp4\"\n\n  mv \"${file%.mp4}-tagged.mp4\" \"$file\"\n\n  # Rate limit\n  sleep 1\ndone\n```\n\n## Troubleshooting\n\n### opustags Not Found\n\n```bash\n# Check if installed\nwhich opustags\n\n# Install if missing\nbrew install opustags  # macOS\nsudo apt install opustags  # Debian\u002FUbuntu\n```\n\n### Invalid UTF-8 in Tags\n\n```bash\n# Clean non-UTF-8 characters before setting\ntitle=$(echo \"$title\" | iconv -f utf-8 -t utf-8 -c)\nopustags -i \"$file\" --set \"TITLE=$title\"\n```\n\n### MusicBrainz No Results\n\n```bash\n# Broaden search (remove artist constraint)\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n\n# Try fuzzy matching\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=recording:${title_enc}~&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Rate Limit Exceeded\n\n```bash\n# Check for 503 response\nif curl -s -I \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=...\" | grep -q \"503\"; then\n  echo \"Rate limit exceeded, waiting 60 seconds...\"\n  sleep 60\nfi\n```\n\n## See Also\n\n- Command: `\u002Ftag-collection`\n- Skill: `@cover-art-embedding`\n- Agent: `@Metadata Curator`\n- MusicBrainz API: https:\u002F\u002Fmusicbrainz.org\u002Fdoc\u002FMusicBrainz_API\n- opustags documentation: https:\u002F\u002Fgithub.com\u002Ffmang\u002Fopustags\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before overwriting existing metadata tags in bulk\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fcover-art-embedding\u002FSKILL.md — Cover art embedding skill used alongside metadata tagging for complete file tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Ftag-collection\u002FSKILL.md — High-level tag-collection command that orchestrates metadata tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fprovenance-tracking\u002FSKILL.md — Record provenance of metadata sources (MusicBrainz, Discogs)\n","# Metadata Tagging Skill\n\nConcrete patterns for applying metadata tags to audio and video files using opustags (Opus) and ffmpeg (MP4\u002FMP3\u002FFLAC).\n\n## opustags (Opus Files)\n\n### Install\n\n```bash\n# macOS\nbrew install opustags\n\n# Ubuntu\u002FDebian\nsudo apt install opustags\n\n# Arch\nsudo pacman -S opustags\n\n# From source\ngit clone https:\u002F\u002Fgithub.com\u002Ffmang\u002Fopustags.git\ncd opustags\ncmake -S . -B build\ncmake --build build\nsudo cmake --install build\n```\n\n### Set Basic Tags\n\n```bash\n# Set all common tags at once\nopustags input.opus \\\n  --set \"TITLE=Both Sides Now\" \\\n  --set \"ARTIST=Joni Mitchell\" \\\n  --set \"ALBUM=Clouds\" \\\n  --set \"ALBUMARTIST=Joni Mitchell\" \\\n  --set \"TRACKNUMBER=12\" \\\n  --set \"DATE=1969\" \\\n  --set \"GENRE=Folk\" \\\n  -o output.opus\n```\n\n### Set Individual Tags\n\n```bash\n# Title\nopustags input.opus --set \"TITLE=Song Title\" -o output.opus\n\n# Artist\nopustags input.opus --set \"ARTIST=Artist Name\" -o output.opus\n\n# Album\nopustags input.opus --set \"ALBUM=Album Name\" -o output.opus\n\n# Album Artist (for compilations)\nopustags input.opus --set \"ALBUMARTIST=Various Artists\" -o output.opus\n\n# Track number\nopustags input.opus --set \"TRACKNUMBER=3\" -o output.opus\n\n# Track number with total\nopustags input.opus --set \"TRACKNUMBER=3\u002F12\" -o output.opus\n\n# Year\nopustags input.opus --set \"DATE=1969\" -o output.opus\n\n# Genre\nopustags input.opus --set \"GENRE=Folk Rock\" -o output.opus\n\n# Comment\nopustags input.opus --set \"COMMENT=Live at Carnegie Hall\" -o output.opus\n```\n\n### In-Place Updates\n\n```bash\n# Modify file in place (overwrites original)\nopustags -i input.opus --set \"TITLE=New Title\"\n\n# Multiple tags in-place\nopustags -i input.opus \\\n  --set \"TITLE=New Title\" \\\n  --set \"ARTIST=New Artist\"\n```\n\n### Read Tags\n\n```bash\n# Display all tags\nopustags input.opus\n\n# Save tags to file\nopustags input.opus > tags.txt\n\n# Check if specific tag exists\nopustags input.opus | grep \"TITLE=\"\n```\n\n### Delete Tags\n\n```bash\n# Delete specific tag\nopustags input.opus --delete \"COMMENT\" -o output.opus\n\n# Delete all tags (keep only vendor string)\nopustags input.opus --delete-all -o output.opus\n```\n\n### Set Cover Art\n\n```bash\n# Embed cover from JPEG file\nopustags input.opus --set-cover cover.jpg -o output.opus\n\n# In-place cover embedding\nopustags -i input.opus --set-cover cover.jpg\n\n# Replace existing cover\nopustags -i input.opus --set-cover new-cover.jpg\n```\n\n### Batch Operations\n\n```bash\n# Set same tags on all files in directory\nfor file in *.opus; do\n  opustags -i \"$file\" \\\n    --set \"ALBUMARTIST=Joni Mitchell\" \\\n    --set \"ALBUM=Blue\" \\\n    --set \"DATE=1971\"\ndone\n\n# Embed same cover into all files\nfor file in *.opus; do\n  opustags -i \"$file\" --set-cover ..\u002Fcover.jpg\ndone\n\n# Set track numbers sequentially\ntrack=1\nfor file in *.opus; do\n  opustags -i \"$file\" --set \"TRACKNUMBER=$track\"\n  ((track++))\ndone\n```\n\n### Extract Cover Art\n\n```bash\n# Extract cover to file (requires parsing output)\nopustags input.opus | grep -A 1000 \"METADATA_BLOCK_PICTURE\" > cover-encoded.txt\n\n# Note: opustags does not have built-in cover extraction\n# Use ffmpeg for this instead (see below)\n```\n\n## ffmpeg (MP4\u002FMP3\u002FFLAC)\n\n### Set MP4 Metadata\n\n```bash\n# Set all common tags\nffmpeg -i input.mp4 -c copy \\\n  -metadata title=\"Both Sides Now\" \\\n  -metadata artist=\"Joni Mitchell\" \\\n  -metadata album=\"Live at Isle of Wight 1970\" \\\n  -metadata date=\"1970\" \\\n  -metadata genre=\"Folk\" \\\n  -metadata comment=\"Restored from VHS\" \\\n  output.mp4\n```\n\n### Set MP3 Metadata (ID3v2.3)\n\n```bash\n# Set tags with ID3v2.3 for compatibility\nffmpeg -i input.mp3 -c copy \\\n  -id3v2_version 3 \\\n  -metadata title=\"Both Sides Now\" \\\n  -metadata artist=\"Joni Mitchell\" \\\n  -metadata album=\"Clouds\" \\\n  -metadata date=\"1969\" \\\n  -metadata track=\"12\u002F14\" \\\n  -metadata genre=\"Folk\" \\\n  output.mp3\n```\n\n### Set FLAC Metadata (Vorbis Comments)\n\n```bash\n# FLAC uses Vorbis comments like Opus\nffmpeg -i input.flac -c copy \\\n  -metadata TITLE=\"Both Sides Now\" \\\n  -metadata ARTIST=\"Joni Mitchell\" \\\n  -metadata ALBUM=\"Clouds\" \\\n  -metadata DATE=\"1969\" \\\n  -metadata TRACKNUMBER=\"12\" \\\n  output.flac\n```\n\n### Embed Cover Art into MP4\n\n```bash\n# Add 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\n### Embed Cover Art into MP3\n\n```bash\n# Add cover with proper ID3v2.3 tags\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\n### Embed Cover Art into FLAC\n\n```bash\n# Add cover to FLAC file\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\n### Extract Cover Art from Any File\n\n```bash\n# Extract first attached picture\nffmpeg -i input.mp3 -an -vcodec copy cover.jpg\n\n# Extract from MP4\nffmpeg -i input.mp4 -map 0:v -map -0:V -c copy cover.jpg\n\n# Extract and convert to PNG\nffmpeg -i input.flac -an -vcodec png cover.png\n```\n\n### Read Metadata\n\n```bash\n# Show all metadata\nffprobe -v quiet -show_format -show_entries format_tags input.mp4\n\n# Show only specific tags\nffprobe -v quiet -show_entries format_tags=title,artist,album input.mp3\n\n# JSON output for parsing\nffprobe -v quiet -print_format json -show_format input.mp4\n```\n\n### Batch MP4 Tagging\n\n```bash\n# Set album and year on all MP4 files\nfor file in *.mp4; do\n  ffmpeg -i \"$file\" -c copy \\\n    -metadata album=\"Live Performances 1970\" \\\n    -metadata date=\"1970\" \\\n    \"${file%.mp4}-tagged.mp4\"\n  mv \"${file%.mp4}-tagged.mp4\" \"$file\"\ndone\n```\n\n## MusicBrainz Lookup\n\n### Recording Search by Artist and Title\n\n```bash\n# Basic search\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:Joni%20Mitchell%20AND%20recording:Both%20Sides%20Now&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0 (contact@example.com)\"\n\n# URL-encode query parameters\nartist=\"Joni Mitchell\"\ntitle=\"Both Sides Now\"\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\ntitle_enc=$(echo \"$title\" | jq -sRr @uri)\n\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Release (Album) Search\n\n```bash\n# Search for release by artist and album\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:Joni%20Mitchell%20AND%20release:Blue&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n\n# Include release group info\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frelease\u002F?query=artist:Joni%20Mitchell%20AND%20release:Blue&inc=release-groups&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Extract Metadata from JSON Response\n\n```bash\n# Get release from recording search\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:Joni%20Mitchell%20AND%20recording:Both%20Sides%20Now&fmt=json\" -H \"User-Agent: MediaCurator\u002F1.0\")\n\n# Extract fields with jq\nalbum=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\nyear=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\nmbid=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].id')\ntrack_num=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].media[0].tracks | map(select(.title == \"Both Sides Now\"))[0].position')\n\necho \"Album: $album\"\necho \"Year: $year\"\necho \"MBID: $mbid\"\necho \"Track: $track_num\"\n```\n\n### Rate Limiting\n\nMusicBrainz allows 1 request per second:\n\n```bash\n# Process multiple files with rate limiting\nfor file in *.opus; do\n  # Extract metadata from filename\n  artist=$(echo \"$file\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\n  title=$(echo \"$file\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n  # Query MusicBrainz\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  title_enc=$(echo \"$title\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  # Extract and apply metadata\n  album=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\n  year=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\n\n  opustags -i \"$file\" \\\n    --set \"ALBUM=$album\" \\\n    --set \"DATE=$year\"\n\n  # Rate limit: wait 1 second\n  sleep 1\ndone\n```\n\n## Filename Parsing Patterns\n\n### Common Patterns\n\n```bash\n# Pattern: \"Artist - Title.ext\"\nartist=$(echo \"$filename\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Artist - Album - Track# - Title.ext\"\nartist=$(echo \"$filename\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\nalbum=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - ([^-]+) - .*\u002F\\1\u002F' | xargs)\ntrack=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - [^-]+ - ([0-9]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[^-]+ - [^-]+ - [^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Track# - Title.ext\" (when artist known)\ntrack=$(echo \"$filename\" | sed -E 's\u002F^([0-9]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^[0-9]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Pattern: \"Title [Quality].ext\" (video)\ntitle=$(echo \"$filename\" | sed -E 's\u002F^(.+) \\[[^]]+\\]\\..*\u002F\\1\u002F' | xargs)\nquality=$(echo \"$filename\" | sed -E 's\u002F.*\\[([^]]+)\\]\\..*\u002F\\1\u002F' | xargs)\n```\n\n### Clean Extracted Strings\n\n```bash\n# Remove leading\u002Ftrailing whitespace\nartist=$(echo \"$artist\" | xargs)\n\n# Remove underscores, convert to spaces\ntitle=$(echo \"$title\" | tr '_' ' ')\n\n# Capitalize first letter of each word\ntitle=$(echo \"$title\" | sed 's\u002F\\b\\(.\\)\u002F\\u\\1\u002Fg')\n```\n\n## Complete Tagging Workflow\n\n### Single File (Opus)\n\n```bash\n#!\u002Fbin\u002Fbash\nfile=\"$1\"\n\n# Extract metadata from filename\nartist=$(echo \"$file\" | sed -E 's\u002F^([^-]+) - .*\u002F\\1\u002F' | xargs)\ntitle=$(echo \"$file\" | sed -E 's\u002F^[^-]+ - ([^.]+)\\..*\u002F\\1\u002F' | xargs)\n\n# Query MusicBrainz\nartist_enc=$(echo \"$artist\" | jq -sRr @uri)\ntitle_enc=$(echo \"$title\" | jq -sRr @uri)\nmbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\")\n\n# Extract metadata\nalbum=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\nyear=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\nmbid=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].id')\ngenre=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0][\"release-group\"][\"primary-type\"]')\n\n# Download cover art\ncurl -s \"https:\u002F\u002Fcoverartarchive.org\u002Frelease\u002F${mbid}\u002Ffront\" -o \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\n# Apply tags\nopustags -i \"$file\" \\\n  --set \"TITLE=$title\" \\\n  --set \"ARTIST=$artist\" \\\n  --set \"ALBUM=$album\" \\\n  --set \"ALBUMARTIST=$artist\" \\\n  --set \"DATE=$year\" \\\n  --set \"GENRE=$genre\" \\\n  --set-cover \"\u002Ftmp\u002Fcover-${mbid}.jpg\"\n\necho \"Tagged: $file\"\n```\n\n### Batch Directory (MP4)\n\n```bash\n#!\u002Fbin\u002Fbash\ndir=\"$1\"\nartist=\"$2\"\n\n# Process all MP4 files\nfor file in \"$dir\"\u002F*.mp4; do\n  # Extract title from filename\n  title=$(basename \"$file\" .mp4)\n\n  # Query MusicBrainz\n  artist_enc=$(echo \"$artist\" | jq -sRr @uri)\n  title_enc=$(echo \"$title\" | jq -sRr @uri)\n  mbdata=$(curl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=artist:${artist_enc}%20AND%20recording:${title_enc}&fmt=json\" \\\n    -H \"User-Agent: MediaCurator\u002F1.0\")\n\n  # Extract metadata\n  album=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].title')\n  year=$(echo \"$mbdata\" | jq -r '.recordings[0].releases[0].date[:4]')\n\n  # Apply tags\n  ffmpeg -i \"$file\" -c copy \\\n    -metadata title=\"$title\" \\\n    -metadata artist=\"$artist\" \\\n    -metadata album=\"$album\" \\\n    -metadata date=\"$year\" \\\n    \"${file%.mp4}-tagged.mp4\"\n\n  mv \"${file%.mp4}-tagged.mp4\" \"$file\"\n\n  # Rate limit\n  sleep 1\ndone\n```\n\n## Troubleshooting\n\n### opustags Not Found\n\n```bash\n# Check if installed\nwhich opustags\n\n# Install if missing\nbrew install opustags  # macOS\nsudo apt install opustags  # Debian\u002FUbuntu\n```\n\n### Invalid UTF-8 in Tags\n\n```bash\n# Clean non-UTF-8 characters before setting\ntitle=$(echo \"$title\" | iconv -f utf-8 -t utf-8 -c)\nopustags -i \"$file\" --set \"TITLE=$title\"\n```\n\n### MusicBrainz No Results\n\n```bash\n# Broaden search (remove artist constraint)\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=recording:${title_enc}&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n\n# Try fuzzy matching\ncurl -s \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=recording:${title_enc}~&fmt=json\" \\\n  -H \"User-Agent: MediaCurator\u002F1.0\"\n```\n\n### Rate Limit Exceeded\n\n```bash\n# Check for 503 response\nif curl -s -I \"https:\u002F\u002Fmusicbrainz.org\u002Fws\u002F2\u002Frecording\u002F?query=...\" | grep -q \"503\"; then\n  echo \"Rate limit exceeded, waiting 60 seconds...\"\n  sleep 60\nfi\n```\n\n## See Also\n\n- Command: `\u002Ftag-collection`\n- Skill: `@cover-art-embedding`\n- Agent: `@Metadata Curator`\n- MusicBrainz API: https:\u002F\u002Fmusicbrainz.org\u002Fdoc\u002FMusicBrainz_API\n- opustags documentation: https:\u002F\u002Fgithub.com\u002Ffmang\u002Fopustags\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fhuman-authorization.md — Seek explicit authorization before overwriting existing metadata tags in bulk\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fcover-art-embedding\u002FSKILL.md — Cover art embedding skill used alongside metadata tagging for complete file tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Ftag-collection\u002FSKILL.md — High-level tag-collection command that orchestrates metadata tagging\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fmedia-curator\u002Fskills\u002Fprovenance-tracking\u002FSKILL.md — Record provenance of metadata sources (MusicBrainz, Discogs)\n",{"name":5,"category":42,"namespace":43,"platforms":44,"description":7},"media-curator","aiwg",[45],"all","main","6754967c344ccb087a8de06972f55a41067b291b","agentic\u002Fcode\u002Fplugins\u002Fmedia-curator\u002Fskills\u002Fmetadata-tagging",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-14 10:46:34",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add jmagly\u002Faiwg --skill metadata-tagging",{"tool":62,"command":63},"bunx","bunx skills add jmagly\u002Faiwg --skill metadata-tagging",{"tool":65,"command":66},"pnpm","pnpm dlx skills add jmagly\u002Faiwg --skill metadata-tagging","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fmedia-curator\u002Fskills\u002Fmetadata-tagging\u002FSKILL.md",true,[],[71,99,123,129,136,150],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":78,"publishedAt":37},"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",[77],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98],"host","host hardening","hardening","read","re","recommendations","remediation","plan","port","verification","Bash","access","only","retention","audit","never","firewall","bind","secrets","request",{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":109,"publishedAt":37},"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",[105,108],{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[110,111,112,82,113,87,114,115,89,116,79,117,91,118,119,94,95,120,121,122],"exposure analysis","analysis","unknown","credentials","collection","ufw","ports","internet","local","scope","reconstruction","operator","write",{"skillNo":124,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":128,"publishedAt":37},"01M70P8QATMPKA78E4FT5D2TNA","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[127],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[81,79,80,90,82,98,85,84,93,86,87,88,89,97,91,92,83,94,95,96],{"skillNo":130,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":135,"publishedAt":37},"01M70NMPVJ5H0JH131P60FW4R8","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fforensics-complete\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[133,134],{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[111,110,94,113,87,114,89,112,79,117,91,118,119,82,95,116,115,120,121,122],{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":143,"publishedAt":37},"01M6CB4DDR0B4NNCFK7ZK7449H","fixture-skill","Exercise rule delivery.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Frule-delivery\u002Fskills\u002Ffixture-skill\u002FSKILL.md",[142],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[144,145,146,147,148,149],"fixture skill","fixture","rule","delivery","true","exercise",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":157,"publishedAt":37},"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",[156],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[158,159,118,160,145],"pi","pi local","duplicate"]