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: Resolve issue #121 by unifying standalone URL normalization across YouTube, X or Twitter, Mastodon, Bluesky, and Threads so all supported providers follow the same embed-or-markdown-fallback contract.
Architecture: Extend the existing scripts/normalize_post_media_links.py and scripts/validate_posts.py paths instead of creating a new parallel normalizer. Keep detection narrow: standalone supported provider URLs on their own line are eligible for official embeds, while provider URLs inside prose normalize only to [url](url). Successful embeds commit with repo-owned provider wrappers plus a *Source:* [Platform](URL) line that preserves the original authored URL. Provider fetch failures degrade to plain markdown links with logged reasons and must still pass validation.
Tech Stack: Python 3, unittest, git hooks, provider embed endpoints, Jekyll markdown content, _layouts/post.html inline post styling
Files:
Modify: tests/test_normalize_post_media_links.py
Step 1: Add failing tests for standalone successful embed conversion across all supported providers
Cover:
?si=...Threads post URL
Cover:
[url](url)no *Source:* line is emitted for markdown fallback
Cover:
[url](url)no embed expansion happens in prose paragraphs
Run:
python3 -m unittest tests/test_normalize_post_media_links.py
Expected: FAIL for the new unified-provider behaviors before implementation.
Files:
scripts/normalize_post_media_links.pyModify: scripts/normalize_wp_embeds.py
Make the classifier distinguish:
generic unsupported URL
Update existing behavior so:
*Source:* [Platform](URL)X or Twitter follows the same embed-or-markdown-fallback rule as the newer providers
For each provider:
*Source:* [Platform](URL) linefall back to [url](url) with a logged reason on failure
When a supported provider URL appears in prose:
normalize only to [url](url)
Do not rewrite:
blockquotes unless later policy changes say otherwise
Run:
python3 -m unittest tests/test_normalize_post_media_links.py tests/test_normalize_wp_embeds.py
Expected: PASS
Files:
Modify: _layouts/post.html
Step 1: Add or align provider-specific wrapper styles
Add styling hooks for:
.post-content .gp-youtube-embed.post-content .gp-x-embed.post-content .gp-mastodon-embed.post-content .gp-bluesky-embed.post-content .gp-threads-embed
Verify the layout rules:
avoid overflow on mobile
Keep these rules in _layouts/post.html because that file already owns embed presentation. Do not split this styling into a second CSS surface during this issue.
Files:
tests/test_validate_posts.pyModify: scripts/validate_posts.py
Cover:
prose-normalized [url](url) passes
Cover:
stale old-shape YouTube or X output that no longer matches the unified contract fails if the policy window applies
Validator should accept:
Validator should reject:
leftover raw standalone supported provider URLs
Step 4: Run focused validator and normalizer tests
Run:
python3 -m unittest tests/test_validate_posts.py tests/test_normalize_post_media_links.py tests/test_normalize_wp_embeds.py
Expected: PASS
Files:
Modify: hooks/pre-commit
Step 1: Confirm the hook still runs the shared normalizer on staged posts
Keep the existing hook architecture. Do not invent a second provider-specific pre-commit entrypoint.
The hook should:
continue through validation
A provider fetch failure should not block commit if the staged file now contains the accepted markdown-link fallback.
Files:
Verify: representative posts in _posts/
Step 1: Build a small representative sample set
Include at least:
one prose paragraph example with a supported provider URL
Use explicit-path or fixture-driven checks before broad rollout.
Confirm:
[url](url)Files:
docs/superpowers/specs/2026-03-27-provider-embed-expansion-design.mdModify: docs/superpowers/plans/2026-03-27-provider-embed-expansion-implementation-plan.md
Run:
python3 -m unittest tests/test_normalize_post_media_links.py tests/test_normalize_wp_embeds.py tests/test_validate_posts.py
Expected: PASS
Run:
python3 scripts/validate_posts.py --today "$(date +%F)"
Expected: PASS
Confirm:
acceptable markdown fallback shape
Use a commit message tied to #121.
#121The PR body should call out that this branch also aligns the older YouTube and X or Twitter behavior with the new shared provider contract instead of leaving them on legacy rules.