Skip to content
Back to skills

Diagram

ASecurity

Render a Mermaid diagram to a self-contained HTML file and a PNG, using the browse shim as the renderer — no heavy diagram toolchain to install.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 3, 2026
ai-agentspythongoshellbashnodegit

Works with

  • terminal

Security analysis

A100/100

Scanned September 3, 2026

npx -y skills add timurgaleev/vibestack --skill diagram --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Diagram?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Diagram
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/timurgaleev-diagram/badge)](https://www.skillsdirectory.com/skills/timurgaleev-diagram)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: diagram
description: |
  Render a Mermaid diagram to a self-contained HTML file and a PNG, using the browse shim as the renderer — no heavy diagram toolchain to install.
allowed-tools:
  - Bash
  - Read
  - Write
triggers:
  - draw a diagram
  - make a mermaid diagram
  - render this flowchart
  - diagram this
  - visualize this as a graph
---

## When to invoke

Use to turn a description or some Mermaid source into a picture — "draw a
diagram", "make a flowchart", "diagram this architecture", "visualize this as a
graph".

# /diagram — Render a Mermaid diagram

vibestack renders **Mermaid** offline. The repo ships the whole renderer as one
self-contained page (`lib/diagram-render/dist/diagram-render.html`, mermaid
pinned at build time), so the browse shim turns your source into SVG with no
network at all. The SVG is inlined into the HTML artifact you keep — it opens in
any browser, on any machine, forever, with nothing to fetch — and the PNG comes
from the same `$B` you already use for QA.

{{include lib/snippets/browse-setup.md}}

### 1. Get the Mermaid source

If the user gave Mermaid, use it. Otherwise write it from their description
(`flowchart`, `sequenceDiagram`, `erDiagram`, `classDiagram`, `gantt`, etc.).

Authoring rules, all in service of one thing — a diagram nobody can read is
worse than a paragraph:

- **Direction follows the subject.** `graph LR` for pipelines and flows, where
  the eye should travel with the data; `graph TD` for hierarchies and
  decompositions, where depth is the point.
- **5-15 nodes is the readable range.** Keep labels to a few words. If the ask
  genuinely needs more, split it into two diagrams along a seam the reader
  already understands (one per subsystem, or overview plus detail) rather than
  shrinking everything to fit.
- **Say what the arrows mean** when a graph mixes kinds of edge — a call, a
  data flow and a deploy step look identical otherwise.

Then pick an output base path. In a git repo, default to a diagram directory
the repo already uses (or `docs/`) with a slug from the diagram's subject, so
the artifacts land somewhere tracked and stop overwriting each other. Outside a
repo, default to `./diagram`. Confirm the path with the user if the diagram is
one they will commit.

Write the Mermaid source to `$OUT.mmd` with the Write tool. Passing it through a
heredoc mangles quotes and backslashes in edge labels, and it is the artifact the
user edits to re-render anyway.

### 2. Render the source to SVG with the offline bundle

The staged copy is content-addressed, so concurrent sessions and mixed vibestack
versions never clobber each other:

```bash
OUT="${OUT:-./diagram}"            # base path; produces $OUT.mmd, $OUT.html, $OUT.png
mkdir -p "$(dirname "$OUT")"

# The renderer is linked into this skill's own directory at install time
# (skills/diagram/renderer -> lib/diagram-render), so it resolves the same way
# in a user-scope install, a project-scope install, and the checkout itself.
BUNDLE=""
for c in "${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/diagram}/renderer/dist/diagram-render.html" \
         "$(git rev-parse --show-toplevel 2>/dev/null)/lib/diagram-render/dist/diagram-render.html"; do
  [ -f "$c" ] && BUNDLE="$c" && break
done
if [ -z "$BUNDLE" ] || [ -z "${B:-}" ] || [ "$("$B" status 2>/dev/null)" = "BROWSE_NOT_AVAILABLE" ]; then
  echo "RENDER_UNAVAILABLE"
else
  SHA=$(shasum -a 256 "$BUNDLE" | cut -c1-16)
  STAGED="${TMPDIR:-/tmp}/vibestack-diagram-render-$SHA.html"
  [ -f "$STAGED" ] || { cp "$BUNDLE" "$STAGED.$$" && mv "$STAGED.$$" "$STAGED"; }
  TAB=$("$B" newtab --json | sed -n 's/.*"tabId":[[:space:]]*\([0-9]*\).*/\1/p')
  [ -z "$TAB" ] && { echo "TAB_OPEN_FAILED — daemon busy? check browse status"; } || {
    "$B" load-html "$STAGED" --tab-id "$TAB"
    "$B" wait '#done' --tab-id "$TAB"
    echo "RENDER_TAB_READY: tab $TAB"
  }
fi
```

**Both failure lines are terminal — STOP, do not continue to Step 3.** With no
`$TAB` and no `$OUT.svg`, the steps below would build an HTML file around a
file that does not exist and screenshot a blank page, reporting success. On
`RENDER_UNAVAILABLE`, say which half is missing. A missing bundle means an
incomplete checkout — re-run `./install` from it. A missing shim means the
browse dependencies were never fetched; `$B status` bootstraps them on first
use and prints `BROWSE_NOT_AVAILABLE` when it cannot (npm absent). On
`TAB_OPEN_FAILED`, report what `$B status` says — the daemon is busy, wedged,
or unable to open a tab — and re-run.

Every `$B js` / `$B wait` / `$B closetab` below MUST pass `--tab-id $TAB`. Without
it the call hits whatever tab is active, which may be a live `/qa` or `/scrape`
session sharing the daemon.

Render the source, reading it from disk inside the page call so no shell quoting
touches the Mermaid text:

```bash
"$B" js "__renderMermaid('diagram-1', $(python3 -c 'import json,sys; print(json.dumps(open(sys.argv[1]).read()))' "$OUT.mmd"))" \
  --tab-id "$TAB" --out "$OUT.svg"
"$B" closetab "$TAB" >/dev/null 2>&1 || true
```

If the call errors, the Mermaid has a syntax problem — read the error, fix
`$OUT.mmd`, and re-render. Do not fall back to a CDN page: rendering is offline
by design, and a silent network fallback turns an air-gapped failure into a
blank diagram nobody notices.

### 3. Inline the SVG into the HTML artifact, then screenshot it

```bash
{
  printf '%s' '<!DOCTYPE html><html><head><meta charset="utf-8"><title>Diagram</title>'
  printf '%s' '<style>body{margin:0;padding:20px;background:#fff;font-family:system-ui}svg{max-width:100%}</style>'
  printf '%s' '</head><body>'
  cat "$OUT.svg"
  printf '%s' '</body></html>'
} > "$OUT.html"

if [ -n "${B:-}" ] && [ "$("$B" status 2>/dev/null)" != "BROWSE_NOT_AVAILABLE" ]; then
  "$B" chain "goto file://$(cd "$(dirname "$OUT")" && pwd)/$(basename "$OUT").html" "wait --load" "screenshot $OUT.png"
  echo "DIAGRAM: $OUT.png (and $OUT.html, $OUT.svg, $OUT.mmd)"
else
  echo "DIAGRAM_HTML_ONLY: $OUT.html — open it in a browser (no shim for PNG)"
fi
```

The SVG is already drawn, so the capture waits on page load rather than on a
fixed timer — nothing is still rendering when the screenshot fires.

### 4. Report

List the artifacts: `.mmd` (the source to edit), `.svg` (vector for docs),
`.html` (opens anywhere, offline), `.png` (for chat and READMEs).

## Notes

- **Mermaid is the supported format.** Excalidraw, DOCX, and multi-page exports
  are not rendered here — for those, hand the user the HTML or use a dedicated
  tool.
- **Fully offline.** The renderer is vendored in the repo, and the HTML artifact
  carries the finished SVG inline — no CDN, no network, at render time or later.
- **PDF-bound diagrams belong to `/make-pdf`.** It renders a ```` ```mermaid ````
  fence as a vector figure inside the document, which beats pasting this skill's
  PNG into a page. Say so when the user's real target is a PDF.
- If `RENDER_UNAVAILABLE` printed, say what is missing and how to get it back
  (`./install` from the checkout for the bundle; `$B status` to bootstrap the
  browse dependencies). Never fall back to a CDN behind the user's back.

{{include lib/snippets/capture-learnings.md}}

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.