{"slug": "i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals", "title": "I built an agent-skill that turns your texts into diagrams and BI-visuals", "summary": "Developer imshaikot released render-visual-skill, an agent skill that lets coding agents generate diagrams, presentation slides, social cards, code snippets, and device mockups as HTML/SVG rendered to PNGs via headless Chromium, with no design tool, API, or npm dependencies. The skill supports sequence diagrams animated into GIFs in pure Node, includes 57 referenceable parts and eight themes, and works with Claude Code, Cursor, GitHub Copilot, VS Code, Codex, Gemini CLI, OpenCode, Amp, and Goose. It is available via the Claude plugin marketplace command 'claude plugin marketplace add imshaikot/render-visual-skill'.", "body_md": "**Your coding agent cannot draw.** This [Agent Skill](https://agentskills.io) fixes that —\ndiagrams, presentation slides, social cards, code snippets and device mockups, authored as\nHTML/SVG and rendered to crisp PNGs by the headless Chromium you already have. No design tool,\nno API, no npm dependencies.\n\ndiagram · `ember` |\nslide · `slate` |\ncard · `paper` |\n\nSequence diagrams animate — each step tweened over several frames, assembled into a looping\nGIF **in pure Node**. Chrome renders the frames in parallel, the built-in zlib decodes them,\nand a hand-rolled GIF89a/LZW encoder with changed-region deltas does the rest:\n\n```\nclaude plugin marketplace add imshaikot/render-visual-skill\nclaude plugin install render-visual-skill@render-visual-skill\n```\n\nWorks in any skills-compatible agent — Claude Code, Cursor, GitHub Copilot / VS Code, Codex,\nGemini CLI, OpenCode, Amp and Goose. [Install](#install) covers the clone-a-branch lane that\nevery agent other than Claude Code uses.\n\nEvery image in this README was rendered by the skill.\n\n[Gallery](#gallery)[Capabilities](#capabilities)[Requirements](#requirements)[Install](#install)[Usage](#usage)[Themes](#themes)[Element library](#element-library)[CLI reference](#cli-reference)[What's inside](#whats-inside)[Why HTML instead of a design tool](#why-html-instead-of-a-design-tool)[Uninstall](#uninstall)[License](#license)\n\nFive more diagram idioms ship as templates, each 1360×740 and assembled from the same parts:\n\nswimlane · `ember` |\ncluster · `slate` |\ndeployment · `blueprint` |\ntree · `paper` |\nmind map · `neon` |\n\nSame markup, different theme:\n\nCode snippets get a Carbon-style window — hand-highlighted with a fixed token→accent mapping, line numbers, a highlight line and diff rows, in any of the eight themes:\n\nDiagrams |\nArchitecture and flow figures — nodes, labelled arrows, return paths, bridged line crossings. 1360×740 |\nPresentation slides |\nKicker, gradient headline, up to three points, footer. 1920×1080; a deck is one file per slide |\nSocial / og cards |\nMark, headline, one-paragraph pitch, chips. 1200×630 |\nCode snippets |\nCarbon-style window, hand-highlighted against a fixed token→accent mapping, line numbers, a highlight line, diff rows |\nSequence diagrams |\nLifelines, calls, returns, activations — rendered static, or animated step by step |\nSwimlanes |\nLanes that own the steps, labelled handoffs, an exception path that stays in its lane |\nTrees |\nOne hierarchy two ways — an indented tree view beside the same tree drawn node-link |\nClusters |\nA dashed boundary, control plane, worker nodes and pods; what is outside it survives a rebuild |\nDeployment diagrams |\n3-D nodes, «stereotypes» and artifact chips: which file lands on which machine, over which protocol |\nMind maps |\nA question in the middle, branches around it, leaves as evidence |\nAnimated GIFs |\nSteps tweened over several frames (`slide` , `fade` , `pop` ), assembled in pure Node. No ffmpeg |\nElement library |\n57 referenceable parts — device frames, infrastructure shapes, a 3-D deployment node, charts, BI furniture and 30 glyphs |\nChart & BI schematics |\nPie, donut, bar, hbar, line, area, stacked, scatter, funnel, gauge, heatmap, sparkline, dashboard, KPI tile, table |\nYour own images |\nScreenshots and photos placed into a device frame or cropped to a shape, inlined before the render |\nEight themes |\nSwap with one flag — every template consumes design tokens, never hard-coded colour |\nAlpha grades |\nEvery colour token has a component twin, so `oklch(var(--a1-raw) / 12%)` gives any transparency of any accent — washes, edges and scrims that cannot drift from the colour they came from |\nTransparent output |\nA real alpha channel via `--transparent` , so a figure drops onto any background |\nParallel-safe |\nEach render claims its own Chrome profile by pid lockfile, and reaps orphans an interrupted run left behind |\nFails loudly |\nA wrong image at exit 0 is the one thing refused outright — blank canvases, missing stylesheets, unreadable images and unknown parts all fail, never render quietly wrong |\n\n**Node 18+****A Chromium-based browser**— Chrome, Chromium, Brave or Edge. Standard install paths and`PATH`\n\nare probed;`CHROME_PATH`\n\noverrides. Without one:`npx @puppeteer/browsers install chrome@stable`\n\n(no root needed).**Network access at render time**, for theme fonts. All eight themes`@import`\n\nfrom`fonts.googleapis.com`\n\n. Offline renders still succeed but fall back to system fonts, so they will not match the previews above.\n\nIt needs a shell and a local browser, so it cannot run on surfaces that have neither — claude.ai chat, the Skills API, cloud sessions and most CI images.\n\n**Claude Code — as a plugin** (gets you `/plugin update`\n\n). From your shell:\n\n```\nclaude plugin marketplace add imshaikot/render-visual-skill\nclaude plugin install render-visual-skill@render-visual-skill\n```\n\nOr from inside Claude Code, as **two separate commands** — run the first, let it finish, then\nrun the second:\n\n```\n/plugin marketplace add imshaikot/render-visual-skill\n/plugin install render-visual-skill@render-visual-skill\n```\n\nImportant\n\n`/plugin marketplace add`\n\nmay open an **Add Marketplace** dialog. Only\n`imshaikot/render-visual-skill`\n\nbelongs in that field. Pasting both lines into it is\nrejected as an invalid `owner/repo`\n\nshorthand — the `/plugin install`\n\nline is a second\ncommand, not part of the source.\n\nThe repeated name is not a typo: `render-visual-skill@render-visual-skill`\n\nreads as\n`plugin@marketplace`\n\n, and here both are called the same thing.\n\n**Any agent — clone the skill into its skills directory.** The `skill`\n\nbranch is published by\nCI with the skill at its root, so the clone target *is* the skill:\n\n```\n# Cursor · VS Code/Copilot · Codex · Gemini CLI · OpenCode · Amp · Goose\ngit clone --depth 1 -b skill https://github.com/imshaikot/render-visual-skill.git \\\n  ~/.agents/skills/render-visual\n\n# Claude Code\ngit clone --depth 1 -b skill https://github.com/imshaikot/render-visual-skill.git \\\n  ~/.claude/skills/render-visual\n```\n\nUpdate with `git -C <that directory> pull --ff-only`\n\n.\n\nNote\n\nCursor, VS Code, OpenCode, Amp and Goose read **both** `~/.agents/skills`\n\nand\n`~/.claude/skills`\n\n. Installing into both shows a duplicate entry in those five — pick one,\nor use the plugin lane for Claude Code and `~/.agents/skills`\n\nfor everything else.\n\nJust ask for a visual:\n\n*\"make a diagram of our auth flow\"**\"turn these notes into a 6-slide deck, paper theme\"**\"an og card for this repo\"**\"put this screenshot in a browser frame\"*\n\nOr drive the renderer by hand:\n\n```\nS=~/.agents/skills/render-visual\nnode $S/scripts/render.mjs  $S/templates/diagram.html  figure.png   --theme slate\nnode $S/scripts/render.mjs  $S/templates/code.html     snippet.png  --theme paper --transparent\nnode $S/scripts/animate.mjs $S/templates/sequence.html sequence.gif --theme ember\n```\n\nThe canvas size comes from the template's `<body>`\n\n; `--scale`\n\ndefaults to 2 (retina).\n`--theme`\n\ninlines the theme, so no `themes/`\n\ndirectory has to sit beside your figure.\n\nWhen a request names no theme, the agent asks rather than guesses — and remembers the\nanswer. Standing choices (theme, where finished images land, scale) live in a\n`.render-visual.json`\n\nat your project root, written only with your consent, so the next\nrender doesn't re-open settled questions:\n\n```\n{ \"theme\": \"slate\", \"output\": \"docs/figures/\", \"scale\": 2 }\n```\n\nAnything said in the prompt beats the file; delete it to change course. The renderer\nitself never reads it — `--theme`\n\nstays explicit on every command.\n\nEvery template consumes tokens only, so one source file renders in any theme.\n\n| Theme | Mood | Fonts |\n|---|---|---|\n`ember` |\nWarm dark — amber-hued neutrals, cyan/ember/magenta accents | Inter Tight + JetBrains Mono |\n`slate` |\nCool dark — violet-leaning neutrals, jewel accents | Space Grotesk + IBM Plex Mono |\n`paper` |\nLight editorial — warm paper, serif display, print restraint | Fraunces + IBM Plex Mono |\n`terminal` |\nNear-black phosphor — mono everything, green/amber | JetBrains Mono |\n`blueprint` |\nDrafting board — cyanotype navy, chalk lines, a grid that reads | Archivo + Roboto Mono |\n`frost` |\nLight UI — cool white, glass surfaces, indigo/teal | Manrope + JetBrains Mono |\n`neon` |\nAfter hours — indigo dark, high-chroma magenta and cyan | Chakra Petch + Fira Code |\n`sepia` |\nAged press — cream stock, brown ink, typewriter mono | Newsreader + Courier Prime |\n\n`templates/palette.html`\n\nis a specimen sheet that renders in whichever theme you hand it and\nlabels itself from the tokens it was given — both fonts, the gradient, the neutrals, the\nalpha ladders, and the same parts dressed by that theme:\n\n```\nnode $S/scripts/render.mjs $S/templates/palette.html palette.png --theme neon\n```\n\n`blueprint` |\n`frost` |\n`neon` |\n`sepia` |\n\nEvery colour token ships a component twin — `--a1-raw`\n\n…`--a4-raw`\n\n, `--ink-raw`\n\n,\n`--ground-raw`\n\n, `--surface-raw`\n\n— three bare OKLCH numbers, so any transparency of any token\nis one expression away:\n\n```\n.badge { background: oklch(var(--a1-raw) / 12%); border: 1px solid oklch(var(--a1-raw) / 45%); color: var(--a1); }\n.scrim { background: oklch(var(--ground-raw) / 72%); }   /* a caption band over a photo */\n```\n\nThe solid token is built from the same components (`--a1: oklch(var(--a1-raw))`\n\n), so a wash\ncan never drift from the colour it is a wash of — and an invariant refuses any theme whose\ncomponent tokens are not composable, because a bad one paints *nothing* rather than failing.\n\nAdding a theme is one CSS file defining the same tokens. Adding a template is one HTML file that consumes only tokens.\n\nFigures assemble from **57 parts** — window/browser/terminal/phone frames, database, server,\nqueue, cloud, router, actor, shield, a 3-D deployment cube, a 30-glyph icon set, and the chart vocabulary below. A\nfigure *references* a part rather than carrying a copy of its geometry:\n\n```\n<g data-part=\"el-database\" data-accent=\"2\" transform=\"translate(70,452)\"/>\n```\n\nEvery part is built from theme tokens, so it restyles with the theme like everything else:\n\nThe standard chart vocabulary — pie, donut, bar, line, area, stacked, scatter, funnel, gauge, heatmap, sparkline — plus BI furniture: a dashboard window, KPI tiles and a data table. Each spends a single accent, graded by opacity where categories must read apart, so a chart sits in a figure without competing with the arrows around it.\n\nThese are **schematics of charts, not charts**: every proportion in them is fixed and\narbitrary, so they can say *\"a dashboard goes here\"* without pretending to be data. Plot real\nnumbers with a real charting library.\n\nPoint `data-image`\n\nat a screenshot or a photo on disk and it lands in a device frame — cropped\nto the shell's own corners, skeleton bars covered — or in any shape you ask for:\n\n```\n<g data-part=\"el-browser\" data-image=\"./shot.png\" data-align=\"top\"/>\n<image data-image=\"./avatar.jpg\" data-shape=\"circle\" x=\"60\" y=\"420\" width=\"160\" height=\"160\"/>\n```\n\nThe bytes are read, format-checked and inlined before Chrome launches, so nothing is left for\nthe browser to fetch and quietly fail at: a missing file, a `.png`\n\nthat is really a text file,\na HEIC, or a remote URL is a fatal error naming the path — never an invisible hole in a figure\nthat still screenshots as a success.\n\n```\nnode $S/scripts/render.mjs <input.html> <output.png> [flags]\n```\n\n| Flag | Default | |\n|---|---|---|\n`--theme` |\nthe page's own | `ember` · `slate` · `paper` · `terminal` · `blueprint` · `frost` · `neon` · `sepia` ; inlined into a temp copy |\n`--scale` |\n`2` |\nOutput multiplier — 1360×740 at 2× is a 2720×1480 PNG |\n`--size` |\nthe `<body>` |\n`WxH` override, e.g. `1200x630` |\n`--transparent` |\noff | Real alpha channel: ground and furniture stripped |\n\n```\nnode $S/scripts/animate.mjs <input.html> <output.gif> [flags]\n```\n\n| Flag | Default | |\n|---|---|---|\n`--fx` |\n`slide` |\nReveal preset: `slide` , `fade` , `pop` |\n`--fps` |\n`25` |\nTween frame rate; 20/25/50 play back exactly |\n`--transition` |\n`450` |\nMilliseconds of tween per step |\n`--delay` |\n`900` |\nMilliseconds of dwell on each completed step |\n`--hold` |\n`2600` |\nMilliseconds on the final frame before looping |\n`--jobs` |\n`4` |\nParallel Chrome instances |\n`--scale` |\n`1` |\nGIFs get heavy fast — stay at 1× |\n`--keep-frames` |\noff | Keep the per-frame PNGs for inspection |\n\n`--theme`\n\nand `--size`\n\nwork as in `render.mjs`\n\n.\n\nRenders are safe to run in parallel — each claims its own Chrome profile via a pid lockfile, and every run first reaps Chromes an interrupted run left holding a slot. Two scripts back that up:\n\n```\nnode $S/scripts/doctor.mjs --prune   # reap orphans, clear stale locks, reclaim profile disk\nnode $S/scripts/selftest.mjs         # ~2m: assert all 22 concurrency and output invariants\n```\n\nReach for `doctor.mjs`\n\nwhen a render fails with *\"is another instance using profile\"*.\n\n```\nskills/render-visual/       the skill — this directory is what gets installed\n  SKILL.md                  workflow, aesthetic rules, layout discipline\n  templates/                diagram · swimlane · tree · cluster · deployment ·\n                            mindmap · sequence (animatable) · code — all 1360×740\n                            slide 1920×1080 · card 1200×630\n                            elements + charts (parts sheets) · palette (theme specimen)\n  parts/                    57 includable elements — frames, shapes, charts,\n                            BI furniture, glyphs\n  themes/                   ember · slate · paper · terminal · blueprint · frost\n                            neon · sepia  (design tokens, swappable)\n  scripts/                  render.mjs (PNG) · animate.mjs (GIF) · gif.mjs (GIF89a encoder)\n                            chrome.mjs (profiles, reaping, guards) · cli.mjs · doctor.mjs\n                            parts.mjs (element includes) · images.mjs (image includes)\n                            markup.mjs · selftest.mjs\n.claude-plugin/             Claude Code plugin + marketplace manifests\npreviews/                   the images above\n```\n\n**Versioned and diffable**— a figure is a text file; regenerating after a copy change is one command** Consistent by construction**— templates consume theme tokens, so nothing is hand-picked per image** Agent-friendly**— an agent writes HTML far better than it steers a canvas\n\nThe skill keeps warm Chrome profiles in your temp directory, so clean those up **before**\nremoving it:\n\n```\nnode <skill directory>/scripts/doctor.mjs --prune   # reclaim profile disk, clear locks\nrm -rf <skill directory>                            # e.g. ~/.agents/skills/render-visual\n```\n\nFor the plugin lane, `/plugin uninstall render-visual-skill`\n\nleaves its cache behind:\n\n```\nrm -rf ~/.claude/plugins/cache/render-visual-skill \\\n       ~/.claude/plugins/marketplaces/render-visual-skill\n```\n\nNothing else is left: all temp state lives under `$TMPDIR/render-visual/`\n\n, and renders never\nwrite into the directory they render from.", "url": "https://wpnews.pro/news/i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals", "canonical_source": "https://github.com/imshaikot/render-visual-skill", "published_at": "2026-08-25 00:55:10+00:00", "updated_at": "2026-08-25 01:13:01.615674+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "generative-ai"], "entities": ["imshaikot", "render-visual-skill", "Claude Code", "Cursor", "GitHub Copilot", "VS Code", "Codex", "Gemini CLI"], "alternates": {"html": "https://wpnews.pro/news/i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals", "markdown": "https://wpnews.pro/news/i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals.md", "text": "https://wpnews.pro/news/i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals.txt", "jsonld": "https://wpnews.pro/news/i-built-an-agent-skill-that-turns-your-texts-into-diagrams-and-bi-visuals.jsonld"}}