Text diagram
A daily-driver collection of skills for agentic coding — a portable, agent-agnostic catalog managed with the vd CLI.
npx -y skills add vanducng/skills --skill text-diagramAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Draw reliable, well-aligned text/ASCII architecture diagrams with nested boxes, arrows, and connectors. Use when user asks to draw/create text diagrams, ASCII art diagrams, box diagrams, or architecture diagrams in plain text. For rendered image artifacts (PNG/SVG), use vd:diagram instead.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.6 KB, as published. Nobody here has run it
Text Diagram Drawing
Draw professional, pixel-perfect text-based architecture diagrams using monospace characters. Every character must align correctly in a monospace font.
Critical Rules (NEVER violate)
- Calculate widths BEFORE drawing. Never freehand a diagram. Always compute column widths, box widths, and total widths first, then render.
- Every line in a box must be the SAME character length. Count characters. Verify.
- Use ONLY ASCII-safe monospace characters for borders:
|,-,+for basic; or Unicode box-drawing (see charset below). Never mix styles in one diagram. - Pad content with spaces to fill the full inner width of every box.
- Vertical connectors (
|or│) must be at the EXACT same column position on every line between two boxes. - After drawing, mentally re-count character positions of the first line, last line, and any connector lines to verify alignment.
- One box-drawing style per diagram. Don't mix
+--+with┌──┐.
Character Sets
Style A: Pure ASCII (safest, works everywhere)
Corners: +
Horiz: -
Vert: |
Arrow: -> or -->
Down: v or V
Cross: +
T-junc: +
Style B: Unicode Light Box Drawing (cleaner look)
Corners: ┌ ┐ └ ┘
Horiz: ─
Vert: │
T-junc: ├ ┤ ┬ ┴
Cross: ┼
Arrow: → ← ↑ ↓
Triangle: ▼ ▲ ► ◄
Style C: Unicode Rounded (friendly look)
Corners: ╭ ╮ ╰ ╯
Horiz: ─
Vert: │
(rest same as Style B)
Style D: Double-line (emphasis/outer containers)
Corners: ╔ ╗ ╚ ╝
Horiz: ═
Vert: ║
T-junc: ╠ ╣ ╦ ╩
Cross: ╬
Style E: Dashed borders (secondary containers)
Vert: ¦ or : or ╎
Horiz: - - - (dash-space-dash)
Width Constraints
- Default max width: 80 characters (standard terminal). Use 120 for wide diagrams.
- If a diagram exceeds the limit, reduce padding, abbreviate labels, or split into multiple diagrams.
- Never use tab characters. Always spaces.
- All Unicode box-drawing chars (U+2500–U+257F) are exactly 1 column wide. Safe to use.
- Avoid: CJK chars (2-wide), emoji (variable width), heavy/dashed variants if cross-platform rendering matters.
Drawing Algorithm
ALWAYS follow these steps in order:
Step 1: Plan the Layout
- List all boxes, their nesting depth, and content lines
- Determine layout direction (top-down, left-right, or mixed)
- Identify connectors between boxes
Step 2: Calculate Dimensions (CRITICAL)
For each box:
inner_width = max(len(line) for line in content_lines) + 2*padding
outer_width = inner_width + 2 (for left/right borders)
For side-by-side boxes:
total_width = sum(outer_widths) + gaps_between_boxes
For container boxes:
container_inner_width = max(total_width_of_children, len(title)) + 2*padding
container_outer_width = container_inner_width + 2
Step 3: Render Top-Down
- Draw each line as a fixed-width string
- Use
.ljust()/ space-padding to ensure every line in a box is the same width - For nested boxes: indent children by container's left border + padding
- Symmetric padding rule: if you indent a child row with 2 spaces on the LEFT after the container's
│, you must reserve 2 spaces on the RIGHT before the closing│. The most common alignment bug is leaving only 1 space on the right.
Step 4: Verify Alignment
- Check: first border line length == last border line length
- Check: all content lines length == border line length
- Check: vertical connector column is consistent across all rows
- Check: side-by-side boxes have matching heights (pad shorter ones with empty lines)
Layout Patterns
Pattern: Container with Title
┌──────────────────────────────┐
│ Container Title │
│ │
│ ┌────────┐ ┌────────┐ │
│ │ Box A │ │ Box B │ │
│ └────────┘ └────────┘ │
│ │
└──────────────────────────────┘
Rule: outer width = 32. Every row (border, title, empty, child rows, bottom) is exactly 32 chars. Right padding before the closing │ mirrors the left padding (2 spaces) plus any extra slack.
Pattern: Vertical Flow with Connector
┌──────────┐
│ Box A │
└────┬─────┘
│
▼
┌──────────┐
│ Box B │
└──────────┘
Rule: The │ and ▼ must be at the same column as ┬. Calculate: left_border + (inner_width / 2) + 1.
Pattern: Horizontal Flow Inside Container
┌──────────────────────────────────────┐
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Step 1 │ → │ Step 2 │ │
│ └─────────┘ └─────────┘ │
│ │
└──────────────────────────────────────┘
Rule: outer width = 40. Arrow → sits at the vertical midpoint of the boxes, between them. Right side keeps ≥2 spaces before the closing │ to mirror left padding.
Pattern: Side-by-Side Boxes (Equal Height)
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Title A │ │ Title B │ │ Title C │
│ (desc) │ │ (desc) │ │ (desc) │
└──────────┘ └──────────┘ └──────────┘
Rule: All boxes MUST have the same number of lines. Pad shorter boxes with blank content lines.
Pattern: Centered Connector Between Sections
┌─────────────────────────┐
│ Section A │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Section B │
└─────────────────────────┘
Rule: Both sections should be the same width. Connector at width / 2.
Common Mistakes to Avoid
| Mistake | Fix |
|---|---|
| Lines in a box have different lengths | Pad ALL lines to max_content_width + 2*padding |
| Right border 1 char short on child rows | Mirror left padding: if left has 2 spaces, right needs 2 spaces too |
| Vertical connector off by 1 | Calculate center: border_start + 1 + floor(inner_width / 2) |
| Nested box wider than parent | Calculate parent width from children FIRST |
| Side-by-side boxes different heights | Count lines, pad shorter box with empty │{spaces}│ lines |
| Right border not aligned | Use fixed-width strings, never rely on "looks right" |
| Mixed border styles | Pick ONE style at the start, use it throughout |
| Arrow not vertically centered on box | Arrow row = top_border_row + 1 + floor(content_lines / 2) |
| Forgot to account for border chars | outer_width = inner_width + 2 (left │ + right │) |
Rendering Checklist (Run mentally after drawing)
- Every box: first border line length == last border line length
- Every box: all content lines == border line length
- Container boxes: wider than all children combined + gaps + padding
- Side-by-side boxes: all same height (line count)
- Vertical connectors: same column on every row
- No trailing spaces inconsistency
- Nested boxes indented consistently
- Arrows aligned to box midpoints
- Right padding mirrors left padding before the closing border
Examples
See references/examples.md for complete worked examples with dimension calculations, and references/advanced-patterns.md for nested architectures, fan-out, and annotated connectors.