Skip to content
Development
Skill

/ascii-diagram

Generate perfectly aligned ASCII diagrams — architecture, flow, sequence, box-and-arrow. Uses a programmatic character-grid approach so alignment is guaranteed by math, not token prediction. Includes post-render verification.

From plugin
citadel
92248 skills7 agents2 MCP
Install
$ npx -y skills add SethGammon/Citadel --skill ascii-diagram --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ascii-diagram

Context preview

The summary Claude sees to decide when to auto-load this skill.

Generate perfectly aligned ASCII diagrams — architecture, flow, sequence, box-and-arrow. Uses a programmatic character-grid approach so alignment is guaranteed by math, not token prediction. Includes post-render verification.

SKILL.md

ascii-diagram.SKILL.md
name: ascii-diagram
license: MIT
description: >-
  Generate perfectly aligned ASCII diagrams — architecture, flow, sequence,
  box-and-arrow. Uses a programmatic character-grid approach so alignment is
  guaranteed by math, not token prediction. Includes post-render verification.
user-invocable: true
auto-trigger: false
trigger_keywords:
  - ascii diagram
  - ascii art
  - box diagram
  - architecture diagram
  - flow diagram
  - sequence diagram
  - draw a diagram
  - text diagram

/ascii-diagram — Perfectly Aligned ASCII Diagrams

Orientation

**Use when:**

  • The user wants any kind of text/ASCII diagram: architecture, flow, sequence,

box-and-arrow, tree, table, org chart, network topology

  • A diagram needs to be embedded in markdown, code comments, or plain text
  • Visual alignment matters

**Do NOT use when:**

  • The user wants an image (suggest Mermaid, PlantUML, or an image tool instead)
  • The diagram is trivial (a single box or a one-line arrow)

**What this skill needs:**

  • A description of what to diagram
  • Optional: preferred style (single-line `+--+`, double-line `╔══╗`, rounded `╭──╮`, heavy `┏━━┓`)
  • Optional: target width constraint

Protocol

Step 1: PLAN THE LAYOUT

Before writing ANY characters, plan the diagram structurally:

1. **Identify elements**: List every box/node and its label text 2. **Identify connections**: List every arrow/line between elements, with optional labels 3. **Choose layout direction**: left-to-right, top-to-bottom, or mixed 4. **Calculate dimensions**:

  • Each box width = max label line length + 4 (2 padding + 2 border)
  • Each box height = label line count + 2 (top + bottom border)
  • Gutters between boxes: minimum 3 characters for arrows (` → `)
  • For vertical arrows: minimum 1 row gap

Write this plan out explicitly before proceeding. Example:

Elements:
  A: "Client" → width=10, height=3
  B: "Server" → width=10, height=3
  C: "Database" → width=12, height=3
Layout: left-to-right
Connections: A→B (HTTP), B→C (SQL)
Total width: 10 + 6 + 10 + 6 + 12 = 44

Step 2: BUILD ON A CHARACTER GRID

Use this JavaScript approach mentally (or actually execute it via Bash if the diagram is complex):

// For complex diagrams, RUN this — don't try to hand-align
class Grid {
  constructor(w, h) {
    this.w = w; this.h = h;
    this.cells = Array.from({length: h}, () => Array(w).fill(' '));
  }
  put(x, y, char) {
    if (x >= 0 && x < this.w && y >= 0 && y < this.h) this.cells[y][x] = char;
  }
  text(x, y, str) {
    for (let i = 0; i < str.length; i++) this.put(x + i, y, str[i]);
  }
  box(x, y, w, h, label) {
    // Top border
    this.put(x, y, '+');
    for (let i = 1; i < w-1; i++) this.put(x+i, y, '-');
    this.put(x+w-1, y, '+');
    // Bottom border
    this.put(x, y+h-1, '+');
    for (let i = 1; i < w-1; i++) this.put(x+i, y+h-1, '-');
    this.put(x+w-1, y+h-1, '+');
    // Sides
    for (let j = 1; j < h-1; j++) {
      this.put(x, y+j, '|');
      this.put(x+w-1, y+j, '|');
    }
    // Label (centered)
    const lines = label.split('\n');
    const startY = y + Math.floor((h - lines.length) / 2);
    for (let li = 0; li < lines.length; li++) {
      const line = lines[li];
      const startX = x + Math.floor((w - line.length) / 2);
      this.text(startX, startY + li, line);
    }
  }
  hArrow(x1, x2, y, label) {
    // Horizontal arrow from x1 to x2 at row y
    const dir = x2 > x1 ? 1 : -1;
    for (let x = x1; x !== x2; x += dir) this.put(x, y, '-');
    this.put(x2, y, dir > 0 ? '>' : '<');
    if (label) {
      const lx = Math.min(x1, x2) + Math.floor((Math.abs(x2-x1) - label.length) / 2);
      this.text(lx, y - 1, label);
    }
  }
  vArrow(x, y1, y2, label) {
    // Vertical arrow from y1 to y2 at column x
    const dir = y2 > y1 ? 1 : -1;
    for (let y = y1; y !== y2; y += dir) this.put(x, y, '|');
    this.put(x, y2, dir > 0 ? 'v' : '^');
    if (label) this.text(x + 2, Math.min(y1, y2) + Math.floor(Math.abs(y2-y1) / 2), label);
  }
  render() {
    return this.cells.map(row => row.join('').trimEnd()).join('\n');
  }
}

**For any diagram with 4+ boxes or crossing connections, ACTUALLY RUN the script via Bash using Node.** Do not attempt to mentally compute grid coordinates for complex diagrams. This is the entire point of the skill — let code handle alignment.

**Pre-built grid engine**: `.citadel/scripts/grid.cjs` provides `Grid` and `autoLayout()`. For auto-layout, pass a JSON spec:

node .citadel/scripts/grid.cjs '{"direction":"horizontal","boxes":[{"id":"a","label":"Input"},{"id":"b","label":"Output"}],"arrows":[{"from":"a","to":"b","label":"data"}]}'

For complex/nested diagrams, use the Grid class directly via `require()`:

node -e "
const {Grid} = require('./.citadel/scripts/grid.cjs');
const g = new Grid(60, 10);
g.box(0, 0, 20, 5, 'Box A');
g.box(30, 0, 20, 5, 'Box B');
g.hArrow(20, 29, 2, 'flow');
console.log(g.render());
"

**Verification**: `.citadel/scripts/verify.cjs` checks alignment:

echo "<diagram>" | node .citadel/scripts/verify.cjs --stdin

Step 3: VERIFY ALIGNMENT

After generating the diagram, verify these properties:

1. **Box closure**: Every `+` corner has matching corners forming a rectangle 2. **Consistent widths**: All rows within a box have the same width 3. **Arrow continuity**: Every arrow is an unbroken sequence of `-`, `|`, or diagonal characters ending in `>`, `<`, `v`, `^` 4. **Label centering**: Labels are centered within their boxes (±1 char) 5. **No trailing whitespace issues**: Right edges of boxes in the same column align vertically

**Verification method**: Count characters. Pick any two `|` side borders that should be in the same column — they MUST be at the same character offset from the start of their respective lines.

If verification fails, fix by adjusting coordinates and re-rendering — do NOT try to patch individual characters.

Step 4: OUTPUT

Present the diagram in a fenced c

Read more
Ships withcitadel

An open-source operating layer for Claude Code and OpenAI Codex. Citadel routes requests, preserves repository state between sessions, coordinates parallel work, applies repository safeguards, and records evidence and handoffs around the coding agent you

Get the whole plugin

Other skills on citadel.