ascii-dependency-graph
Render an ASCII dependency graph from a JSON structure.
Render an ASCII box-drawing memory map (an address-space layout diagram) from a JSON description. Use whenever a response needs a memory map, memory layout, address map, or address-space diagram for ANY architecture (Commodore VIC-20/C64, x86 real-mode/segmented, ARM/MCU
$ npx -y skills add rohingosling/claude-skills --skill ascii-memory-map --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/ascii-memory-mapContext preview
The summary Claude sees to decide when to auto-load this skill.
Render an ASCII box-drawing memory map (an address-space layout diagram) from a JSON description. Use whenever a response needs a memory map, memory layout, address map, or address-space diagram for ANY architecture (Commodore VIC-20/C64, x86 real-mode/segmented, ARM/MCU
name: ascii-memory-map description: Render an ASCII box-drawing memory map (an address-space layout diagram) from a JSON description. Use whenever a response needs a memory map, memory layout, address map, or address-space diagram for ANY architecture (Commodore VIC-20/C64, x86 real-mode/segmented, ARM/MCU flash+SRAM, flat 32/64-bit, etc.). Separates the map's DATA from its RENDERING and offloads all box drawing, column alignment, address formatting, and size-proportional block heights to a deterministic Python renderer, so the model only authors compact JSON. disable-model-invocation: false
Render an ASCII memory map using the Python script at `${CLAUDE_SKILL_DIR}/scripts/render_ascii_memory_map.py`.
Author the map as JSON (the *data*), choose presentation flags (the *rendering*), run the script, and paste its output into a fenced code block. Let the script do all box drawing, alignment, address formatting, and height scaling — do not hand-draw memory maps.
Every piece of text has exactly one home, decided by what it refers to:
| Class | What it is | Where it goes | |-------|------------|---------------| | **Address** | A hex/decimal boundary coordinate | Left gutter, on the divider that *opens* the block (its low-address edge) | | **Label** | The block's short name | Inside the box, first body row | | **Description** | Optional elaboration (extent, contents) | Inside the box, further body rows | | **Comment / note** | Extrinsic annotation — register writes, bit patterns, caveats, consequences | Right of the box, anchored to the first body row with an arrow; continuations align beneath, no arrow |
Decisive test: text that **names or describes the contents** of a span is intrinsic → goes **inside** (label/description); text that **says something about** the span (a value, a constraint, a cross-reference) is extrinsic → goes **outside** (comment). A bare boundary coordinate goes in the **gutter**. Divider and border lines carry only the address — never a label or a comment. The renderer enforces all of this.
1. Construct a JSON object describing the memory map (schema below). Store addresses as numeric/hex strings — the renderer formats them for display, so the same data can be shown as `$0400`, `0x0400`, `0400h`, `0040:0000`, or `01024` by changing one flag.
2. Write the JSON to a temporary file in the current project's working directory (e.g. `memmap.json`).
3. Run the renderer (use `python3` on macOS/Linux, `python` on Windows):
python3 "${CLAUDE_SKILL_DIR}/scripts/render_ascii_memory_map.py" memmap.json [flags]Defaults can also be set inside the JSON in a `"render": { ... }` object; CLI flags override the JSON, which overrides the built-in defaults.
4. Copy the output into the target markdown inside a fenced code block.
5. Delete the temporary JSON file.
Top-level keys:
| Key | Type | Meaning | |-----|------|---------| | `title` | string | Optional heading printed above the map | | `render` | object | Optional default values for any flag below (underscore_case keys, e.g. `"address_format": "c"`) | | `blocks` | array | The memory regions (required) |
Each block:
| Field | Type | Meaning | |-------|------|---------| | `start` | int or string | Start address (required). Strings accept `$XXXX`, `0xXXXX`, `XXXXh`, `SSSS:OOOO`, or a bare numeral (hex by default) | | `end` | int or string | Inclusive end address (last byte). Optional — if omitted, inferred from the next block's `start` | | `size` | int or string | Alternative to `end`; accepts `2K`, `0x800`, `4096`, `64KB` | | `label` | string | The region name (inside the box) | | `description` | string or array | Extra inside-the-box line(s) | | `comments` | string or array | Outside-the-box note(s); the first is arrow-anchored, the rest align beneath | | `rows` | int | Force this block's body height (overrides scaling) |
| Flag | Default | Purpose | |------|---------|---------| | `--address-format` | `commodore` | `commodore` (`$0400`), `c` (`0x0400`), `intel` (`0400h`), `plain` (`0400`), `segmented` (`0040:0000`), `decimal`, `decimal-padded` | | `--address-width` | auto | Digit count (4 = 16-bit, 8 = 32-bit…); auto-sized from the largest address if omitted | | `--input-radix` | `hex` | How to read bare numeric *strings* in the JSON (`hex` / `decimal`); integers are always decimal | | `--hex-case` | `upper` | `upper` / `lower` hex digits | | `--origin` | `top` | `top` = low address at top (addresses increase downward); `bottom` = low address at bottom | | `--scale` | `on` | `on` / `off` — size-proportional block heights | | `--scale-mode` | `log` | `log` / `linear` / `sqrt` taper | | `--min-rows` / `--max-rows` | `1` / `6` | Clamp for scaled block heights | | `--style` | `unicode` | `unicode` / `heavy` / `double` / `ascii` (`+ - |` for non-Unicode terminals) | | `--width` | `auto` | Interior box width: `auto` (longest label) or an integer | | `--comment-arrow` | `◄─` | Outside-note connector (`<-` in `ascii` style) | | `--no-comments` | off | Suppress all outside notes | | `--show-size` | off | Append each region's computed size inside its box | | `--show-end` | off | Show the end address on the closing boundary | | `--show-gaps` | off | Draw unmapped ranges between blocks as their own gap blocks | | `--gap-label` | `· · ·` | Label used for auto-generated gap blocks | | `--paragraph` | `16` | Bytes per segment for `segmented` addresses | | `--title` | — | Override the JSON `title` |
With `--scale on` (default), a block's body height is `max( rows_needed_for_text, clamp( round(min_rows + f(size)·(max_rows−min_rows)), min_rows, max_rows ) )`, where `f` is a log/linear/sqrt normalisation of the block's size between the smallest and largest sized blocks. The log taper means one very large region is only a few rows taller than its neighbours — a visual cue to relative size, not a to
Claude Code plugin marketplace. A curated collection of my publicly-shared Agent Skills, each packaged as an installable plugin.
Render an ASCII dependency graph from a JSON structure.
Generate a hierarchical ASCII diagram that can be used for representing folder structures, decomposition diagrams, or any other kind of diagrams that might…