--- pr: 134 title: feat(draw-image): SVG template renderer for on-brand covers --- ## Что сделано Реализован плагин `draw-image` для генерации on-brand обложек (covers) в стиле slaid098.dev. Структура: - `.opencode/tools/draw-image.ts` — opencode plugin (spawnSync → cli.ts) - `.opencode/draw-image/` — render-движок: render.mjs (sharp → PNG), cli.ts, src/ (config/slot-parser/fit/recolor/resolve/render), templates/cover.svg, brand.json, fonts/ (Geist TTF), icons/lucide/ (2007 иконок), brand-logos/ (пусто v1) - Слот-система: HTML-комментарии в SVG → SlotSpec (name/x/y/w/h/fit/recolor/bg/border/radius) - Lucide-иконки: npm-пакет lucide-static, postinstall sync в icons/lucide/, recolor stroke → accent - Шрифты: Geist Sans TTF bundled, переданы в sharp через fontFiles - Идемпотентность: cover.meta.json с sha256(brand+template+args) - Тесты: 48 vitest (unit + integration + e2e) + 5 pytest (tool wrapper via _ts_loader.mjs) - CI: npm ci + npm test в .opencode/draw-image добавлены в test job - dependabot.yml: битый `/config` → `/.opencode` + `/.opencode/draw-image` - docs/project-map/README.md обновлён ## Почему В продуктовых репо slaid098 нет ни одного cover-ассета — обложки рисовались вручную или отсутствовали. Утилита обеспечивает always on-brand генерацию: цвета захардкожены в шаблоне, Geist TTF bundled, Lucide line-icons recolor в accent. Эталон — covers из slaid098-dev/src/apps/. ## Pending — ## Watch out - `import.meta.dir` в draw-image.ts (не `import.meta.url`) — _ts_loader.mjs заменяет только `.dir` - CLI использует `--experimental-strip-types` (Node 22+) для запуска .ts напрямую - lucide-static postinstall копирует 2007 SVG в icons/lucide/ (committим только mic/play, остальные через npm) - sharp fontFiles требует Geist TTF в fonts/ (committим Regular + Bold)