7.1 KiB
Asset Library Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Generate a media-type-first asset library under each run folder so humans can browse videos, images, logos, poster frames, thumbnails, and variants without navigating source-mirrored URLs.
Architecture: Extend scripts/save_visual_assets.py after the existing raw download path. The raw assets/discovered/ archive remains the canonical downloaded copy, and a new library layer copies retrieved files into assets/library/ with readable filenames plus JSON/TSV manifests under assets/manifests/.
Tech Stack: Python standard library, unittest, existing shell/Python watch scripts.
Task 1: Metadata Extraction Helpers
Files:
-
Modify:
scripts/save_visual_assets.py -
Test:
tests/test_save_visual_assets.py -
Step 1: Write failing tests
Add tests that build a fake run with WordPress media JSON containing:
{
"id": 433313,
"slug": "3-in-1-2",
"mime_type": "video/mp4",
"post": 433326,
"source_url": "https://komodostation.com/wp-content/uploads/2026/04/3-in-1.mp4",
"title": {"rendered": "3 in 1"},
"media_details": {
"width": 1920,
"height": 850,
"filesize": 12242748,
"sizes": {},
},
}
Expected helper output:
{
"media_id": "433313",
"parent_id": "433326",
"title": "3 in 1",
"width": 1920,
"height": 850,
"filesize": 12242748,
}
- Step 2: Run tests and confirm failure
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: failure because metadata helper functions do not exist.
- Step 3: Implement metadata helpers
Add small helpers in scripts/save_visual_assets.py:
def extract_media_metadata(obj: dict, source_path: str) -> dict:
details = obj.get("media_details") if isinstance(obj.get("media_details"), dict) else {}
title = obj.get("title") if isinstance(obj.get("title"), dict) else {}
return {
"media_id": str(obj.get("id") or ""),
"parent_id": str(obj.get("post") or ""),
"title": title.get("rendered") or obj.get("slug") or "",
"slug": obj.get("slug") or "",
"mime": obj.get("mime_type") or "",
"width": details.get("width") or "",
"height": details.get("height") or "",
"filesize": details.get("filesize") or "",
"source_json": source_path,
}
Update collection to store metadata alongside URL and MIME.
- Step 4: Run tests and confirm pass
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: all tests pass.
Task 2: Library Classification And Filenames
Files:
-
Modify:
scripts/save_visual_assets.py -
Test:
tests/test_save_visual_assets.py -
Step 1: Write failing tests
Add tests for these classification outcomes:
("video/mp4", "3-in-1.mp4", "3 in 1", 1920, 850) -> "videos"
("image/svg+xml", "controllerLogo.svg", "controllerLogo", "", "") -> "logos"
("image/png", "videoframe_789.png", "videoframe_789", 1920, 1080) -> "poster-frames"
("image/avif", "d760...-150x150.avif", "spec image", 150, 150) -> "thumbnails"
("image/avif", "d760...-2048x988.avif", "spec image", 2048, 988) -> "variants"
("image/avif", "d760....avif", "spec image", 2048, 988) -> "images"
Add a filename test:
build_library_filename(metadata, url, "steam-controller") == "steam-controller_433313_3-in-1_1920x850.mp4"
- Step 2: Run tests and confirm failure
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: failure because classification and filename helpers do not exist.
- Step 3: Implement helpers
Add helpers:
slugify(value: str) -> strhas_size_suffix(url: str) -> boolis_thumbnail_size(width, height, url) -> boolinfer_hardware(metadata, url, sources) -> strclassify_library_category(metadata, url) -> strbuild_library_filename(metadata, url, hardware) -> str
Use steam-controller, steam-machine, steam-frame, and unknown hardware slugs.
- Step 4: Run tests and confirm pass
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: all tests pass.
Task 3: Generate Library Files And Manifests
Files:
-
Modify:
scripts/save_visual_assets.py -
Test:
tests/test_save_visual_assets.py -
Step 1: Write failing integration test
Create a test fake run containing a video, logo, poster frame, thumbnail, and variant. Mock downloads with valid bytes. Run save_visual_assets.main() and assert:
assets/library/videos/steam-controller_433313_3-in-1_1920x850.mp4
assets/library/logos/steam-controller_413728-controller-logo.svg
assets/library/poster-frames/steam-controller_433298_videoframe-789_1920x1080.png
assets/library/thumbnails/steam-controller_433298_videoframe-789_150x150.png
assets/library/variants/steam-controller_433477_spec-image_2048x988.avif
assets/manifests/asset-library.json
assets/manifests/asset-library.tsv
Assert manifest rows include original URL, raw path, library path, category, hardware, media ID, parent ID, dimensions, MIME, detected format, and source JSON.
- Step 2: Run tests and confirm failure
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: failure because library generation does not exist.
- Step 3: Implement library generation
After a download is retrieved or found cached:
- Build metadata.
- Choose category.
- Build a readable filename.
- Copy the raw downloaded file into
assets/library/<category>/. - Resolve filename collisions by appending
-2,-3, etc. - Write JSON and TSV manifests under
assets/manifests/.
- Step 4: Run tests and confirm pass
Run:
python3 -m unittest tests/test_save_visual_assets.py
Expected: all tests pass.
Task 4: Regenerate Current Run And Verify
Files:
-
Runtime artifacts:
/Users/sean/steam_hardware_watch/2026-04-26/assets/library -
Runtime artifacts:
/Users/sean/steam_hardware_watch/2026-04-26/assets/manifests -
Step 1: Regenerate assets
Run:
python3 scripts/save_visual_assets.py --run-dir /Users/sean/steam_hardware_watch/2026-04-26 --base-dir /Users/sean/steam_hardware_watch
- Step 2: Verify media-type folders
Run:
find /Users/sean/steam_hardware_watch/2026-04-26/assets/library -maxdepth 2 -type f | sed 's#.*/assets/library/##' | sort | head -n 80
Expected: files appear under videos/, images/, logos/, poster-frames/, thumbnails/, and variants/.
- Step 3: Verify manifests
Run:
python3 -m json.tool /Users/sean/steam_hardware_watch/2026-04-26/assets/manifests/asset-library.json >/dev/null
test -s /Users/sean/steam_hardware_watch/2026-04-26/assets/manifests/asset-library.tsv
Expected: exit 0.
- Step 4: Run final tests
Run:
python3 -m py_compile scripts/save_visual_assets.py
python3 -m unittest tests/test_save_visual_assets.py
Expected: all tests pass.