π MakerWorld Description Skill
π What
Manages MakerWorld model descriptions as git-tracked DESCRIPTION.md files. Supports three flows:
- Extract (MakerWorld β Git): Scrape a MakerWorld model page and produce a clean
DESCRIPTION.md + images
- Update (Git β» Git): Update an existing
DESCRIPTION.md after model changes β new changelog entries, feature bullets, images
- Publish (Git β MakerWorld): Convert
DESCRIPTION.md to HTML for pasting into MakerWorld's CKEditor
π§ Extract Flow
Given a MakerWorld model URL, extract the description into a DESCRIPTION.md file.
Steps
Ask the user which model this is for and where to save it:
- Target repo (
homeracker or homeracker-exclusive)
- Model name (e.g.
core, foot, frontpanel)
- Output path defaults to
models/<name>/makerworld/DESCRIPTION.md
Fetch the page using fetch_webpage with query "model description details" and the MakerWorld URL.
Parse the Description section. The description content is between the ### Description heading and the ### Comment & Rating section. Extract only this content. Ignore:
- Navigation elements, cookie banners, footer
- Print Profile section, Bill of Materials
- Comment & Rating section and all comments
- Remixes, Related Models sections
- "We use cookies" banner
Clean the markdown:
- Convert extracted content to well-formatted markdown
- Preserve: headings (##, ###), bold/italic, bullet lists, numbered lists, links, images, linked images (
[](url)), horizontal rules
- Strip:
[Image: Image] placeholders, duplicate blank lines, trailing whitespace
- Keep image URLs as-is initially (they'll be downloaded next)
- Use
<img> tags instead of markdown image syntax for all images. This allows preserving the width attribute. Use width="800" for images whose native width is β₯ 800px; for smaller images use their native width. Exceptions: HomeRacker logo (width="300"), Ko-fi QR code (width="328"). Do NOT set height β omitting it lets the browser scale proportionally. Example:<img src="https://raw.githubusercontent.com/.../logo.webp" alt="Logo" width="800">
For linked images, wrap the <img> in an <a> tag:<a href="https://target-url"><img src="https://raw.githubusercontent.com/.../image.webp" alt="Alt" width="400"></a>
- Alignment is lost during extraction:
fetch_webpage strips style attributes, so centered text/headings from MakerWorld come through as plain markdown. This is a known limitation. After extraction, add a note at the bottom of the DESCRIPTION.md:<!-- TODO: Review alignment β fetch_webpage strips style attributes. Compare with MakerWorld page and wrap centered elements in HTML blocks. -->
When fixing alignment, use:
<h2 style="text-align: center">Title</h2> for centered headings
<p style="text-align: center">...</p> for centered paragraphs, images, or links
- This renders correctly on GitHub (HTML passthrough) and in
md-to-mw.py
- Detect orphan linked images:
fetch_webpage drops <img> elements inside <a> tags, producing empty links like [](https://...). Collect all such [](url) patterns β these are linked images whose src was lost. See step 5a for resolution
- Be aware of invisible drops:
fetch_webpage silently drops <iframe> embeds (YouTube videos, etc.) with no trace at all β just blank whitespace. See step 5b for resolution
Download images:
- Identify all image URLs in the description (from
makerworld.bblmw.com CDN or other sources)
- Skip external reference images (e.g.
encrypted-tbn0.gstatic.com meme images) β keep those as URLs
- Download MakerWorld CDN images to the assets repo:
assets/<target-repo>/models/<name>/makerworld/images/
- Use descriptive filenames based on context (e.g.
diagonal_supports.png, showcase_rack.jpg)
- After downloading, get pixel dimensions with
python cmd/export/image_dimensions.py <images-dir> (for reference only β do not use native dimensions for width)
- Standard image width: Use
width="800" for all description images whose native width is β₯ 800px. For smaller images, use their native width. Exceptions: HomeRacker logo (width="300"), Ko-fi QR code (width="328"). This ensures a uniform look across all model descriptions.
- Check for common images: Some images are shared across all models (e.g.
collection_banner.webp, kofi_qr_code.webp). These live in assets/common/makerworld/images/. If a downloaded image already exists there (same content), delete the per-model copy and reference the common one: https://raw.githubusercontent.com/kellerlabs/assets/main/common/makerworld/images/filename.webp
- Reference model-specific images using absolute URLs in
<img> tags, applying the standard width rule above: use width="800" when the native width is β₯ 800px; otherwise use the native width. Example: <img src="https://raw.githubusercontent.com/kellerlabs/assets/main/<target-repo>/models/<name>/makerworld/images/filename.png" alt="Description" width="800">
5a. Resolve orphan linked images (from step 4):
- For each
[](url) pattern found, present the user with a numbered list showing the link target URL
- Ask the user to open the MakerWorld page in a browser and identify what image is displayed for each link (e.g. a logo, a model thumbnail, a collection banner)
- The user should provide the image URL (right-click β "Copy image address") or a description
- Once URLs are obtained: download to
assets/<target-repo>/models/<name>/makerworld/images/, replace the empty link with a proper linked image using absolute URL: [](url)
- If the user cannot provide the URL, insert a TODO comment in the markdown:
<!-- TODO: linked image missing for url -->
5b. Resolve missing embeds (from step 4):
Add YAML frontmatter to the top of DESCRIPTION.md:
---
makerworld_url: https://makerworld.com/en/models/<id>-<slug>
extracted: YYYY-MM-DD
---
Save the file to the target path.
Verify by reading back the file and checking:
- Frontmatter is valid YAML
- All images have been downloaded
- No
[Image: Image] placeholders remain
- No orphan
[](url) empty links remain (all resolved or marked with TODO)
- Embedded videos are accounted for (user confirmed none missing, or added)
- Markdown renders with proper heading hierarchy
π€ Publish Flow
Convert a DESCRIPTION.md file to HTML for pasting into MakerWorld.
Steps
- Direct the user to run the conversion script:
python cmd/export/md-to-mw.py models/<name>/makerworld/DESCRIPTION.md
- This generates
DESCRIPTION.html in the same directory (gitignored).
- Instruct the user to open the HTML file in a browser, select all (
Ctrl+A), copy (Ctrl+C), then paste into MakerWorld's description editor.
οΏ½ Update Flow
Update an existing DESCRIPTION.md after model changes (new release, new features, removed parts, etc.).
Steps
Locate the description: Read the model's DESCRIPTION.md and its YAML frontmatter (extracted or created date, makerworld_url).
Detect the source repo: Infer the repo from the file path (homeracker or homeracker-exclusive). Present the suggestion and ask for confirmation before proceeding.
Read the changelog: Read CHANGELOG.md in the source repo. Identify releases since the frontmatter date (extracted or created) or, if no date is usable, since the last changelog entry already mentioned in the description.
Filter model-relevant changes: From the new releases, extract only changes that affect this model's user-facing description:
- β
New features, new parts, breaking changes, removed parts
- β CI/infra, docs-only, refactors, dependency bumps
Present a summary of relevant changes and ask the user to confirm or adjust before editing.
Update the description:
- Changelog section: Add new entries at the top of the
π Changelog list. Follow the existing emoji + version + dash + description pattern. Drop entries that are no longer the most recent 3β4 (keep the list concise).
- Feature sections: Add, update, or remove bullets in "What's in the Box" or equivalent sections to reflect added/removed parts or features.
- Flag rewrites: If a feature was removed or significantly changed, flag the affected section with a
<!-- TODO: verify β feature X was removed/changed in vN.N.N --> comment and ask the user for guidance.
Check for new images: Scan assets/<repo>/models/<name>/makerworld/images/ for images added since the last update. If new images exist, suggest where to insert them. If none exist but the new features would benefit from visuals, ask the user whether to add any.
Update frontmatter: Add or update the updated field with today's date:
---
makerworld_url: https://makerworld.com/en/models/<id>-<slug>
extracted: 2026-04-13
updated: 2026-04-19
---
Verify: Read back the file and check:
- Frontmatter dates are consistent (updated β₯ extracted/created)
- Changelog entries are in reverse-chronological order
- No stale feature bullets remain for removed parts
- Image references still resolve
Publish reminder: After committing, remind the user to re-run md-to-mw.py and re-paste into MakerWorld if the model is already published (check makerworld_url β TBD).
οΏ½π File Convention
models/<name>/makerworld/
βββ <name>.scad # MakerWorld parametric source
βββ DESCRIPTION.md # Model description (source of truth)
βββ DESCRIPTION.html # Generated HTML (gitignored)
βββ renders/ # Auto-generated render previews
β βββ <name>_mw_assembly_view.png
β βββ <name>_mw_plate_1.png
Images are stored in the assets repo (kellerlabs/assets):
assets/<repo>/models/<name>/makerworld/images/
βββ showcase.jpg
βββ diagonal_supports.png
Common images shared across all models are stored in the assets repo:
assets/common/makerworld/images/
βββ homeracker_logo_banner.webp # HomeRacker logo (linked to homeracker.org)
βββ collection_banner.webp # Official HomeRacker Collection banner
βββ kofi_qr_code.webp # Ko-fi donation QR code
Reference via: https://raw.githubusercontent.com/kellerlabs/assets/main/common/makerworld/images/<file>
π Common Description Elements
All HomeRacker MakerWorld descriptions share recurring elements. When extracting, verify these are present:
- Centered header block β everything from the top of the description until the first video embed or model-specific content must be centered using HTML style blocks. The logo is always
width="300" and linked to homeracker.org. Pattern:<p style="text-align: center">Intro text</p>
<h2 style="text-align: center">Model Title</h2>
<p style="text-align: center"><a href="https://homeracker.org/"><img src=".../common/makerworld/images/homeracker_logo_banner.webp" alt="HomeRacker Logo" width="300"></a></p>
<p style="text-align: center">Subtitle / links</p>
- Collection banner β linked image to the Official HomeRacker Collection. Uses
common/makerworld/images/collection_banner.webp
- Ko-fi QR code β in the β Support section. Uses
common/makerworld/images/kofi_qr_code.webp
- "π‘ What is HomeRacker?" section (non-core models only) β includes the HomeRacker Core video embed (
g8k6X_axYug) immediately after the heading, followed by links to homeracker.org and the collection
These elements are often dropped by fetch_webpage (logo as orphan linked image, video as invisible iframe). Always check for them during extraction.
β οΈ Important Notes
- Cross-repo skill: Requires both the source repo (
homeracker or homeracker-exclusive) and the kellerlabs/assets repo. Maintainers push images directly to assets/main. Outside collaborators must open a PR on the assets repo for image changes.
DESCRIPTION.md is the source of truth. Always edit it in git, never in MakerWorld directly.
- After editing
DESCRIPTION.md, re-run md-to-mw.py and re-paste into MakerWorld.
- The conversion script embeds local images as base64 data URIs so the HTML is fully self-contained β no broken links, no browser permissions needed. External image URLs (http/https) are passed through unchanged.
- Since images are now hosted in the
kellerlabs/assets repo with absolute URLs, md-to-mw.py passes them through directly β no base64 encoding needed for assets-hosted images.
- Alignment: Use inline HTML blocks (
<h2 style="text-align: center">, <p style="text-align: center">) to preserve centered headings, images, and text from MakerWorld. These render correctly on GitHub and pass through to md-to-mw.py HTML output.
- Image sizing: Use
width="800" as the standard for all description images whose native width is β₯ 800px; for smaller images use their native width (omit height so images scale proportionally). Exceptions: HomeRacker logo (width="300"), Ko-fi QR code (width="328").
- MakerWorld CDN images (from
makerworld.bblmw.com) should be downloaded to the assets repo during extraction. External reference images (memes, badges, etc.) can stay as external URLs.
- Humanize after writing: once a
DESCRIPTION.md is created or edited, run the humanizer skill over it to strip AI tells before publishing.
π Known Limitations
fetch_webpage drops linked images
fetch_webpage converts HTML to markdown but loses <img> elements nested inside <a> tags. This produces empty links like [](https://some-url) where a linked image (<a href="..."><img src="..."></a>) existed in the original HTML.
Common patterns affected:
- Logo/banner images linking to external sites (e.g. HomeRacker logo β homeracker.org)
- Model thumbnail images linking to other MakerWorld models
- Collection banner images linking to MakerWorld collections
Workaround: Step 5a in the Extract Flow asks the user to manually supply the missing image URLs by inspecting the page in a browser.
fetch_webpage silently drops embedded iframes
fetch_webpage completely discards <iframe> elements (YouTube embeds, etc.) with no trace β no placeholder, no URL, just blank whitespace. Unlike linked images which leave a detectable [](url) pattern, embedded videos are entirely invisible in the output.
Common patterns affected:
- YouTube video embeds in description sections
- Any other
<iframe>-based content
Workaround: Step 5b in the Extract Flow explicitly asks the user whether embedded videos exist on the page. Videos are stored as linked YouTube thumbnails in DESCRIPTION.md. During publish, md-to-mw.py automatically converts these to CKEditor 5 <figure class="media"> embeds with data-oembed-url, which MakerWorld's editor recognises as native video embeds.
Source: kellerlabs/homeracker β distributed by TomeVault.
1---2name: kellerlabs-homeracker-homeracker3description: π MakerWorld Description Skill4---56# π MakerWorld Description Skill78## π What910Manages MakerWorld model descriptions as git-tracked `DESCRIPTION.md` files. Supports three flows:11121. **Extract** (MakerWorld β Git): Scrape a MakerWorld model page and produce a clean `DESCRIPTION.md` + images132. **Update** (Git β» Git): Update an existing `DESCRIPTION.md` after model changes β new changelog entries, feature bullets, images143. **Publish** (Git β MakerWorld): Convert `DESCRIPTION.md` to HTML for pasting into MakerWorld's CKEditor1516## π§ Extract Flow1718Given a MakerWorld model URL, extract the description into a `DESCRIPTION.md` file.1920### Steps21221. **Ask the user** which model this is for and where to save it:23 - Target repo (`homeracker` or `homeracker-exclusive`)24 - Model name (e.g. `core`, `foot`, `frontpanel`)25 - Output path defaults to `models/<name>/makerworld/DESCRIPTION.md`26272. **Fetch the page** using `fetch_webpage` with query `"model description details"` and the MakerWorld URL.28293. **Parse the Description section**. The description content is between the `### Description` heading and the `### Comment & Rating` section. Extract only this content. Ignore:30 - Navigation elements, cookie banners, footer31 - Print Profile section, Bill of Materials32 - Comment & Rating section and all comments33 - Remixes, Related Models sections34 - "We use cookies" banner35364. **Clean the markdown**:37 - Convert extracted content to well-formatted markdown38 - Preserve: headings (##, ###), bold/italic, bullet lists, numbered lists, links, images, linked images (`[](url)`), horizontal rules39 - Strip: `[Image: Image]` placeholders, duplicate blank lines, trailing whitespace40 - Keep image URLs as-is initially (they'll be downloaded next)41 - **Use `<img>` tags instead of markdown image syntax** for all images. This allows preserving the `width` attribute. Use `width="800"` for images whose native width is β₯ 800px; for smaller images use their native width. Exceptions: HomeRacker logo (`width="300"`), Ko-fi QR code (`width="328"`). Do NOT set `height` β omitting it lets the browser scale proportionally. Example:42 ```html43 <img src="https://raw.githubusercontent.com/.../logo.webp" alt="Logo" width="800">44 ```45 For linked images, wrap the `<img>` in an `<a>` tag:46 ```html47 <a href="https://target-url"><img src="https://raw.githubusercontent.com/.../image.webp" alt="Alt" width="400"></a>48 ```49 - **Alignment is lost during extraction**: `fetch_webpage` strips `style` attributes, so centered text/headings from MakerWorld come through as plain markdown. This is a known limitation. After extraction, add a note at the bottom of the DESCRIPTION.md:50 ```markdown51 <!-- TODO: Review alignment β fetch_webpage strips style attributes. Compare with MakerWorld page and wrap centered elements in HTML blocks. -->52 ```53 When fixing alignment, use:54 - `<h2 style="text-align: center">Title</h2>` for centered headings55 - `<p style="text-align: center">...</p>` for centered paragraphs, images, or links56 - This renders correctly on GitHub (HTML passthrough) and in `md-to-mw.py`57 - **Detect orphan linked images**: `fetch_webpage` drops `<img>` elements inside `<a>` tags, producing empty links like `[](https://...)`. Collect all such `[](url)` patterns β these are linked images whose `src` was lost. See step 5a for resolution58 - **Be aware of invisible drops**: `fetch_webpage` silently drops `<iframe>` embeds (YouTube videos, etc.) with no trace at all β just blank whitespace. See step 5b for resolution59605. **Download images**:61 - Identify all image URLs in the description (from `makerworld.bblmw.com` CDN or other sources)62 - Skip external reference images (e.g. `encrypted-tbn0.gstatic.com` meme images) β keep those as URLs63 - Download MakerWorld CDN images to the **assets repo**: `assets/<target-repo>/models/<name>/makerworld/images/`64 - Use descriptive filenames based on context (e.g. `diagonal_supports.png`, `showcase_rack.jpg`)65 - After downloading, get pixel dimensions with `python cmd/export/image_dimensions.py <images-dir>` (for reference only β do not use native dimensions for `width`)66 - **Standard image width**: Use `width="800"` for all description images whose native width is β₯ 800px. For smaller images, use their native width. Exceptions: HomeRacker logo (`width="300"`), Ko-fi QR code (`width="328"`). This ensures a uniform look across all model descriptions.67 - **Check for common images**: Some images are shared across all models (e.g. `collection_banner.webp`, `kofi_qr_code.webp`). These live in `assets/common/makerworld/images/`. If a downloaded image already exists there (same content), delete the per-model copy and reference the common one: `https://raw.githubusercontent.com/kellerlabs/assets/main/common/makerworld/images/filename.webp`68 - Reference model-specific images using absolute URLs in `<img>` tags, applying the standard width rule above: use `width="800"` when the native width is β₯ 800px; otherwise use the native width. Example: `<img src="https://raw.githubusercontent.com/kellerlabs/assets/main/<target-repo>/models/<name>/makerworld/images/filename.png" alt="Description" width="800">`69705a. **Resolve orphan linked images** (from step 4):71 - For each `[](url)` pattern found, present the user with a numbered list showing the link target URL72 - Ask the user to open the MakerWorld page in a browser and identify what image is displayed for each link (e.g. a logo, a model thumbnail, a collection banner)73 - The user should provide the image URL (right-click β "Copy image address") or a description74 - Once URLs are obtained: download to `assets/<target-repo>/models/<name>/makerworld/images/`, replace the empty link with a proper linked image using absolute URL: `[](url)`75 - If the user cannot provide the URL, insert a TODO comment in the markdown: `<!-- TODO: linked image missing for url -->`76775b. **Resolve missing embeds** (from step 4):78 - Ask the user: "Are there any embedded videos (YouTube, etc.) on the MakerWorld description page that should be included?"79 - If yes, ask for the YouTube video URL(s) and where they appear in the description80 - Insert a markdown-compatible YouTube link in the appropriate location. Use a linked thumbnail image:81 ```markdown82 [](https://www.youtube.com/watch?v=<VIDEO_ID>)83 ```84 - `md-to-mw.py` automatically converts these to CKEditor `<figure class="media">` embeds during publish85866. **Add YAML frontmatter** to the top of `DESCRIPTION.md`:87 ```yaml88 ---89 makerworld_url: https://makerworld.com/en/models/<id>-<slug>90 extracted: YYYY-MM-DD91 ---92 ```93947. **Save** the file to the target path.95968. **Verify** by reading back the file and checking:97 - Frontmatter is valid YAML98 - All images have been downloaded99 - No `[Image: Image]` placeholders remain100 - No orphan `[](url)` empty links remain (all resolved or marked with TODO)101 - Embedded videos are accounted for (user confirmed none missing, or added)102 - Markdown renders with proper heading hierarchy103104## π€ Publish Flow105106Convert a `DESCRIPTION.md` file to HTML for pasting into MakerWorld.107108### Steps1091101. Direct the user to run the conversion script:111 ```bash112 python cmd/export/md-to-mw.py models/<name>/makerworld/DESCRIPTION.md113 ```1142. This generates `DESCRIPTION.html` in the same directory (gitignored).1153. Instruct the user to open the HTML file in a browser, select all (`Ctrl+A`), copy (`Ctrl+C`), then paste into MakerWorld's description editor.116117## οΏ½ Update Flow118119Update an existing `DESCRIPTION.md` after model changes (new release, new features, removed parts, etc.).120121### Steps1221231. **Locate the description**: Read the model's `DESCRIPTION.md` and its YAML frontmatter (`extracted` or `created` date, `makerworld_url`).1241252. **Detect the source repo**: Infer the repo from the file path (`homeracker` or `homeracker-exclusive`). Present the suggestion and ask for confirmation before proceeding.1261273. **Read the changelog**: Read `CHANGELOG.md` in the source repo. Identify releases since the frontmatter date (`extracted` or `created`) or, if no date is usable, since the last changelog entry already mentioned in the description.1281294. **Filter model-relevant changes**: From the new releases, extract only changes that affect this model's user-facing description:130 - β
New features, new parts, breaking changes, removed parts131 - β CI/infra, docs-only, refactors, dependency bumps132133 Present a summary of relevant changes and ask the user to confirm or adjust before editing.1341355. **Update the description**:136 - **Changelog section**: Add new entries at the top of the `π Changelog` list. Follow the existing emoji + version + dash + description pattern. Drop entries that are no longer the most recent 3β4 (keep the list concise).137 - **Feature sections**: Add, update, or remove bullets in "What's in the Box" or equivalent sections to reflect added/removed parts or features.138 - **Flag rewrites**: If a feature was removed or significantly changed, flag the affected section with a `<!-- TODO: verify β feature X was removed/changed in vN.N.N -->` comment and ask the user for guidance.1391406. **Check for new images**: Scan `assets/<repo>/models/<name>/makerworld/images/` for images added since the last update. If new images exist, suggest where to insert them. If none exist but the new features would benefit from visuals, ask the user whether to add any.1411427. **Update frontmatter**: Add or update the `updated` field with today's date:143 ```yaml144 ---145 makerworld_url: https://makerworld.com/en/models/<id>-<slug>146 extracted: 2026-04-13147 updated: 2026-04-19148 ---149 ```1501518. **Verify**: Read back the file and check:152 - Frontmatter dates are consistent (updated β₯ extracted/created)153 - Changelog entries are in reverse-chronological order154 - No stale feature bullets remain for removed parts155 - Image references still resolve1561579. **Publish reminder**: After committing, remind the user to re-run `md-to-mw.py` and re-paste into MakerWorld if the model is already published (check `makerworld_url` β `TBD`).158159## οΏ½π File Convention160161```162models/<name>/makerworld/163βββ <name>.scad # MakerWorld parametric source164βββ DESCRIPTION.md # Model description (source of truth)165βββ DESCRIPTION.html # Generated HTML (gitignored)166βββ renders/ # Auto-generated render previews167β βββ <name>_mw_assembly_view.png168β βββ <name>_mw_plate_1.png169```170171Images are stored in the **assets repo** (`kellerlabs/assets`):172```173assets/<repo>/models/<name>/makerworld/images/174βββ showcase.jpg175βββ diagonal_supports.png176```177178Common images shared across all models are stored in the assets repo:179```180assets/common/makerworld/images/181βββ homeracker_logo_banner.webp # HomeRacker logo (linked to homeracker.org)182βββ collection_banner.webp # Official HomeRacker Collection banner183βββ kofi_qr_code.webp # Ko-fi donation QR code184```185186Reference via: `https://raw.githubusercontent.com/kellerlabs/assets/main/common/makerworld/images/<file>`187188## π Common Description Elements189190All HomeRacker MakerWorld descriptions share recurring elements. When extracting, verify these are present:1911921. **Centered header block** β everything from the top of the description until the first video embed or model-specific content must be centered using HTML style blocks. The logo is always `width="300"` and linked to `homeracker.org`. Pattern:193 ```html194 <p style="text-align: center">Intro text</p>195 <h2 style="text-align: center">Model Title</h2>196 <p style="text-align: center"><a href="https://homeracker.org/"><img src=".../common/makerworld/images/homeracker_logo_banner.webp" alt="HomeRacker Logo" width="300"></a></p>197 <p style="text-align: center">Subtitle / links</p>198 ```1992. **Collection banner** β linked image to the Official HomeRacker Collection. Uses `common/makerworld/images/collection_banner.webp`2003. **Ko-fi QR code** β in the β Support section. Uses `common/makerworld/images/kofi_qr_code.webp`2014. **"π‘ What is HomeRacker?" section** (non-core models only) β includes the HomeRacker Core video embed (`g8k6X_axYug`) immediately after the heading, followed by links to homeracker.org and the collection202203These elements are often dropped by `fetch_webpage` (logo as orphan linked image, video as invisible iframe). Always check for them during extraction.204205## β οΈ Important Notes206207- **Cross-repo skill**: Requires both the source repo (`homeracker` or `homeracker-exclusive`) and the [`kellerlabs/assets`](https://github.com/kellerlabs/assets) repo. Maintainers push images directly to `assets/main`. Outside collaborators must open a PR on the assets repo for image changes.208- `DESCRIPTION.md` is the **source of truth**. Always edit it in git, never in MakerWorld directly.209- After editing `DESCRIPTION.md`, re-run `md-to-mw.py` and re-paste into MakerWorld.210- The conversion script embeds local images as base64 data URIs so the HTML is fully self-contained β no broken links, no browser permissions needed. External image URLs (http/https) are passed through unchanged.211- Since images are now hosted in the `kellerlabs/assets` repo with absolute URLs, `md-to-mw.py` passes them through directly β no base64 encoding needed for assets-hosted images.212- **Alignment**: Use inline HTML blocks (`<h2 style="text-align: center">`, `<p style="text-align: center">`) to preserve centered headings, images, and text from MakerWorld. These render correctly on GitHub and pass through to `md-to-mw.py` HTML output.213- **Image sizing**: Use `width="800"` as the standard for all description images whose native width is β₯ 800px; for smaller images use their native width (omit `height` so images scale proportionally). Exceptions: HomeRacker logo (`width="300"`), Ko-fi QR code (`width="328"`).214- MakerWorld CDN images (from `makerworld.bblmw.com`) should be downloaded to the assets repo during extraction. External reference images (memes, badges, etc.) can stay as external URLs.215- **Humanize after writing**: once a `DESCRIPTION.md` is created or edited, run the [`humanizer`](../humanizer/SKILL.md) skill over it to strip AI tells before publishing.216217## π Known Limitations218219### `fetch_webpage` drops linked images220221`fetch_webpage` converts HTML to markdown but loses `<img>` elements nested inside `<a>` tags. This produces empty links like `[](https://some-url)` where a linked image (`<a href="..."><img src="..."></a>`) existed in the original HTML.222223**Common patterns affected**:224- Logo/banner images linking to external sites (e.g. HomeRacker logo β homeracker.org)225- Model thumbnail images linking to other MakerWorld models226- Collection banner images linking to MakerWorld collections227228**Workaround**: Step 5a in the Extract Flow asks the user to manually supply the missing image URLs by inspecting the page in a browser.229230### `fetch_webpage` silently drops embedded iframes231232`fetch_webpage` completely discards `<iframe>` elements (YouTube embeds, etc.) with **no trace** β no placeholder, no URL, just blank whitespace. Unlike linked images which leave a detectable `[](url)` pattern, embedded videos are entirely invisible in the output.233234**Common patterns affected**:235- YouTube video embeds in description sections236- Any other `<iframe>`-based content237238**Workaround**: Step 5b in the Extract Flow explicitly asks the user whether embedded videos exist on the page. Videos are stored as linked YouTube thumbnails in `DESCRIPTION.md`. During publish, `md-to-mw.py` automatically converts these to CKEditor 5 `<figure class="media">` embeds with `data-oembed-url`, which MakerWorld's editor recognises as native video embeds.239240---241> Source: [kellerlabs/homeracker](https://github.com/kellerlabs/homeracker) β distributed by [TomeVault](https://tomevault.io).242<!-- tomevault:4.0:skill_md:2026-06-29 -->