{
  "markdown": "# hdldiagZero\n\nAn agent skill that turns an HDL / RTL / SoC architecture description into a clean SVG block diagram. Color-codes blocks by clock domain, distinguishes AXI and TileLink variants, draws CDC blocks with a split fill, omits clock / reset / JTAG / debug clutter by default, and validates the output geometry so lines never pass through blocks.\n\nThe skill is packaged as a Claude Code plugin: the runtime files live under [skills/hdldiagzero/](skills/hdldiagzero/) and are described by [.claude-plugin/plugin.json](.claude-plugin/plugin.json) and [.claude-plugin/marketplace.json](.claude-plugin/marketplace.json). Claude Code users install via the marketplace flow; other agent runtimes (Codex, custom) can use [install.py](install.py) for a direct copy.\n\n## Index\n\n- [Usage](#usage)\n- [Sample Output](#sample-output)\n- [Features](#features)\n- [Files](#files)\n- [Install](#install)\n- [Testing](#testing)\n- [Author](#author)\n- [License](#license)\n\n## Usage\n\nOnce installed, ask the agent something like *\"draw the top-level RTL\"* in any HDL project and the skill activates. By default it uses the light theme and depth 1 (top + direct children); add \"dark mode\" or \"two levels deep\" to override. The agent extracts the architecture, writes a JSON spec next to the SVG, validates the spec, runs the renderer, and validates the SVG geometry.\n\nYou can also drive the toolchain manually:\n\n```\npython validate_spec.py spec.json\npython render.py --theme dark spec.json out.svg\npython validate.py out.svg\n```\n\nEach validator exits 0 on PASS, 1 when validation reports violations, and 2 for usage / parse errors. The spec validator may print non-fatal authoring hints (such as unused legend domains or a likely reversed CDC split) while still exiting 0. The SVG validator prints the exact violation count in stdout; one bad route may trigger multiple reports. Each violation prints with coordinates so the agent (or a human) can adjust the JSON.\n\n## Sample Output\n\n### Hierarchy depth 1 - top + direct children\n\nGenerated from [test_spec.json](test_spec.json):\n\nLight mode:\n\n<a href=\"sample_output.svg\">\n  <img src=\"sample_output.svg\" alt=\"Sample hdldiagZero SVG output\">\n</a>\n\nDark mode:\n\n<a href=\"sample_output_dark.svg\">\n  <img src=\"sample_output_dark.svg\" alt=\"Sample hdldiagZero dark-mode SVG output\">\n</a>\n\n### Full SoC top-level\n\nGenerated from [test_spec_soc.json](test_spec_soc.json) - application SoC with a CPU complex, CPU-local L2 cache, CPU-to-AXI bridge, AXI interconnect, on-chip SRAM, DMA, DDR controller, off-chip DDR4, APB bridge, and an APB peripherals subsystem across four clock domains (cpu / axi / ddr / apb):\n\nLight mode:\n\n<a href=\"sample_soc.svg\">\n  <img src=\"sample_soc.svg\" alt=\"Full SoC top-level diagram\">\n</a>\n\nDark mode:\n\n<a href=\"sample_soc_dark.svg\">\n  <img src=\"sample_soc_dark.svg\" alt=\"Full SoC top-level dark-mode diagram\">\n</a>\n\n### OpenTitan Earl Grey sample\n\nGenerated from [test_spec_opentitan.json](test_spec_opentitan.json) - an overview-style sample of the OpenTitan Earl Grey SoC with Ibex, TL-UL fabric, memory controllers, secure services, peripheral fabric, interrupts, and always-on control paths:\n\nLight mode:\n\n<a href=\"sample_opentitan.svg\">\n  <img src=\"sample_opentitan.svg\" alt=\"OpenTitan Earl Grey sample diagram\">\n</a>\n\nDark mode:\n\n<a href=\"sample_opentitan_dark.svg\">\n  <img src=\"sample_opentitan_dark.svg\" alt=\"OpenTitan Earl Grey sample dark-mode diagram\">\n</a>\n\n### OpenTitan Earl Grey depth 2\n\nGenerated from [test_spec_opentitan_depth2.json](test_spec_opentitan_depth2.json) - the same SoC expanded into grouped Ibex core internals, secure-services, and peripheral-subsystem blocks:\n\nLight mode:\n\n<a href=\"sample_opentitan_depth2.svg\">\n  <img src=\"sample_opentitan_depth2.svg\" alt=\"OpenTitan Earl Grey depth-2 sample diagram\">\n</a>\n\nDark mode:\n\n<a href=\"sample_opentitan_depth2_dark.svg\">\n  <img src=\"sample_opentitan_depth2_dark.svg\" alt=\"OpenTitan Earl Grey depth-2 dark-mode diagram\">\n</a>\n\n### Clock-domain lanes\n\nGenerated from [test_spec_lanes.json](test_spec_lanes.json) - an RHS-style acquisition pipeline where each clock domain gets its own tinted lane spanning the canvas:\n\nLight mode:\n\n<a href=\"sample_lanes.svg\">\n  <img src=\"sample_lanes.svg\" alt=\"Sample hdldiagZero lane-style SVG output\">\n</a>\n\nDark mode:\n\n<a href=\"sample_lanes_dark.svg\">\n  <img src=\"sample_lanes_dark.svg\" alt=\"Sample hdldiagZero lane-style dark-mode SVG output\">\n</a>\n\n### Hierarchy depth 2 - children + grandchildren\n\nGenerated from [test_spec_depth2.json](test_spec_depth2.json) - a GbE MAC where the TX/RX paths are expanded into their internal descriptor -> FIFO/CDC -> MAC pipelines:\n\nLight mode:\n\n<a href=\"sample_depth2.svg\">\n  <img src=\"sample_depth2.svg\" alt=\"Sample hdldiagZero depth-2 SVG output\">\n</a>\n\nDark mode:\n\n<a href=\"sample_depth2_dark.svg\">\n  <img src=\"sample_depth2_dark.svg\" alt=\"Sample hdldiagZero depth-2 dark-mode SVG output\">\n</a>\n\n## Features\n\n- **JSON-spec-driven render**: the agent extracts a small architecture spec; the renderer (`render.py`) produces the SVG. The renderer owns geometry - the agent doesn't pick coordinates.\n- **Clock-domain coloring** with a tuned Material-tone palette. Each domain has a separate fill and dark border. CDC blocks (`domain_b: ...`) use `cdc_side` to place the second domain on the `left`, `right`, `top`, or `bottom` half nearest its connected neighbors.\n- **External / off-chip blocks** (`external: true`) use neutral grey without a domain; when clocked, they can retain a domain fill and use a dashed border to preserve the chip-boundary distinction.\n- **Edge-side external blocks** with optional `side` hints (`left`, `right`, `top`, `bottom`) so I/O blocks can sit on canvas edges and expose inward-facing ports.\n- **Per-block sizing** with optional `w` / `h` overrides for compact leaves or larger hub blocks, while `grid.cell_w` / `grid.cell_h` remain the diagram-wide defaults.\n- **Quarter-step placement** with `row` / `col` values like `1.25` or `2.5` for pulling related blocks closer together without compressing the whole diagram.\n- **Compact multi-line block labels** with `lines: [...]` for dense SoC diagrams where `label` + `sublabel` is too rigid.\n- **Functional background bands** (`bands`) and clock-domain lanes (`lanes`) for broad visual grouping, plus `legend: false` / `legend: compact` when large diagrams should spend the canvas on architecture instead of keys.\n- **Explicit extraction guidance** so clean architecture defaults can be overridden for implementation-detail diagrams without adding inert renderer metadata.\n- **Edge styles per kind**: `axi-mm`, `axi-lite`, `axi-stream`, `tilelink`, `cdc` (purple dashed), `generic`. Distinct strokes and arrowheads, plus a connection-styles legend below the clock-domain legend.\n- **Manhattan single-bend routing** with **interval-coloring lane assignment**: parallel edges sharing a gutter that *actually* overlap in y/x get distinct lanes; non-overlapping edges share a lane so labels stay in the gutter midpoint.\n- **Row/column gutter detours** for same-row or same-column edges that need to pass around intermediate blocks.\n- **WCAG-style text contrast**: block text auto-flips between light and dark by relative-luminance contrast so labels read on every fill, including CDC gradients.\n- **Light + dark themes** (`theme: dark` in the JSON or `--theme dark` on the CLI). Dark mode uses pure black canvas with brightened accent colors for arrows, labels, and external blocks.\n- **Edge bitwidth labels** at the bend midpoint, with a subtle pill mask so the line doesn't pierce the text.\n- **Geometry validator** (`validate.py`) catches line-through-block crossings, exact arrow-route overlaps, parallel-arrow collisions, unnecessary route loops, floating endpoints, stub arrows (shaft shorter than arrowhead), tangential block entry/exit, labels overlapping foreign blocks, arrows piercing other arrows' labels, multiple endpoints meeting at the same block port, and missing edge labels.\n\n## Files\n\n### Plugin runtime (installed into the agent's skill directory)\n\nAll runtime files live under [`skills/hdldiagzero/`](skills/hdldiagzero/) - the plugin shape Claude Code expects. `install.py` mirrors this directory into the destination, so a manual install ends up with the same files in the same relative layout.\n\n| File | Purpose |\n| --- | --- |\n| [skills/hdldiagzero/SKILL.md](skills/hdldiagzero/SKILL.md) | Skill definition consumed by the agent runtime (description, workflow). |\n| [skills/hdldiagzero/LICENSE](skills/hdldiagzero/LICENSE) | MIT license bundled with the runtime. |\n| [skills/hdldiagzero/agents/openai.yaml](skills/hdldiagzero/agents/openai.yaml) | Marketplace/UI metadata for skill lists and default prompts. |\n| [skills/hdldiagzero/assets/hdldiagzero-small.svg](skills/hdldiagzero/assets/hdldiagzero-small.svg) | Small icon used by marketplace/UI metadata. |\n| [skills/hdldiagzero/render.py](skills/hdldiagzero/render.py) | JSON -> SVG renderer. |\n| [skills/hdldiagzero/validate.py](skills/hdldiagzero/validate.py) | SVG geometry validator (exit code 0/1/2; stdout carries the violation count). |\n| [skills/hdldiagzero/validate_spec.py](skills/hdldiagzero/validate_spec.py) | JSON spec validator - run before the renderer to catch structural errors. |\n| [skills/hdldiagzero/references/schema.md](skills/hdldiagzero/references/schema.md) | Full JSON schema, loaded on demand. |\n| [skills/hdldiagzero/references/extraction.md](skills/hdldiagzero/references/extraction.md) | HDL extraction patterns: top discovery, hierarchy walking, exclusions, AXI classification. |\n| [skills/hdldiagzero/references/validation.md](skills/hdldiagzero/references/validation.md) | Fix recipes for each validator violation. |\n\n### Plugin / marketplace metadata\n\n| File | Purpose |\n| --- | --- |\n| [.claude-plugin/plugin.json](.claude-plugin/plugin.json) | Plugin manifest (name, version, author, license, repository). Claude Code reads this when installing. |\n| [.claude-plugin/marketplace.json](.claude-plugin/marketplace.json) | Marketplace manifest. Lets the same repo also serve as a one-plugin marketplace; users add it with `/plugin marketplace add lcapossio/hdldiagZero`. |\n\n### Repo-only (not in the plugin runtime)\n\n| File | Purpose |\n| --- | --- |\n| [install.py](install.py) | Direct (non-marketplace) install path: copies `skills/hdldiagzero/` into a destination dir. Claude defaults; override with `--dst` for Codex / custom runtimes. |\n| [tests.py](tests.py) | Self-tests: validators, renderer light + dark, install dry-run. |\n| [CHANGELOG.md](CHANGELOG.md) | Release notes for published plugin versions. |\n| [test_spec.json](test_spec.json) | Clean renderer smoke-test spec (hierarchy depth 1 - top + direct children). |\n| [test_spec_depth2.json](test_spec_depth2.json) | Depth-2 sample spec (GbE MAC with TX/RX pipelines expanded). |\n| [test_spec_lanes.json](test_spec_lanes.json) | Clock-domain lanes sample (RHS-style acquisition pipeline). |\n| [test_spec_soc.json](test_spec_soc.json) | Full SoC top-level sample (CPU + IC + DMA + DDR + APB peripherals). |\n| [test_spec_opentitan.json](test_spec_opentitan.json) | OpenTitan Earl Grey overview sample. |\n| [test_spec_opentitan_depth2.json](test_spec_opentitan_depth2.json) | OpenTitan Earl Grey depth-2 grouped sample with Ibex internals. |\n| [sample_output.svg](sample_output.svg) / [sample_output_dark.svg](sample_output_dark.svg) | Tracked light/dark renderer output from `test_spec.json`. |\n| [sample_depth2.svg](sample_depth2.svg) / [sample_depth2_dark.svg](sample_depth2_dark.svg) | Tracked light/dark renderer output from `test_spec_depth2.json`. |\n| [sample_lanes.svg](sample_lanes.svg) / [sample_lanes_dark.svg](sample_lanes_dark.svg) | Tracked light/dark renderer output from `test_spec_lanes.json`. |\n| [sample_soc.svg](sample_soc.svg) / [sample_soc_dark.svg](sample_soc_dark.svg) | Tracked light/dark renderer output from `test_spec_soc.json`. |\n| [sample_opentitan.svg](sample_opentitan.svg) / [sample_opentitan_dark.svg](sample_opentitan_dark.svg) | Tracked light/dark renderer output from `test_spec_opentitan.json`. |\n| [sample_opentitan_depth2.svg](sample_opentitan_depth2.svg) / [sample_opentitan_depth2_dark.svg](sample_opentitan_depth2_dark.svg) | Tracked light/dark renderer output from `test_spec_opentitan_depth2.json`. |\n| [not_sample_broken_validator_fixture.svg](not_sample_broken_validator_fixture.svg) | Intentionally broken validator regression fixture. It is supposed to fail with exactly 20 violation reports; it is not sample output. |\n| [pyproject.toml](pyproject.toml) | Ruff lint config. |\n| [.github/workflows/ci.yml](.github/workflows/ci.yml) | GitHub Actions: ruff + `python tests.py` on Linux / macOS / Windows x Python 3.10, 3.12. |\n| [LICENSE](LICENSE), [README.md](README.md) | Repo-root license and docs (the plugin runtime carries its own copy of LICENSE under `skills/hdldiagzero/`). |\n\n## Install\n\n### Claude Code (recommended)\n\n```\n/plugin marketplace add lcapossio/hdldiagZero\n/plugin install hdldiagzero@hdldiag-marketplace\n```\n\nClaude Code clones the repo, reads [.claude-plugin/marketplace.json](.claude-plugin/marketplace.json), and mounts [skills/hdldiagzero/](skills/hdldiagzero/) as the active skill. Restart Claude Code afterward.\n\nThe marketplace entry is pinned to the published tag in [.claude-plugin/marketplace.json](.claude-plugin/marketplace.json). To pick up a newer published tag after upgrading the marketplace entry, run:\n\n```\n/plugin marketplace update hdldiag-marketplace\n/plugin install hdldiagzero@hdldiag-marketplace\n```\n\n### Other runtimes (Codex, custom)\n\nRequires Python 3.10+. From the repo root:\n\n```\npython install.py                                # Claude Code direct copy: ~/.claude/skills/hdldiagzero\npython install.py --runtime codex                # Codex default: ~/.codex/skills/hdldiagzero\npython install.py --dst /opt/agent-skills/hdldiagzero\n```\n\nCopies the contents of [skills/hdldiagzero/](skills/hdldiagzero/) into the destination directory. Restart your runtime.\n\n## Testing\n\n```\npython tests.py\n```\n\nRuns the same checks as CI:\n\n1. **Validator regression** - runs `validate.py` on the intentionally broken `not_sample_broken_validator_fixture.svg` and asserts exactly 20 violation reports.\n2. **Spec validator** - confirms `validate_spec.py` accepts a known-good spec and rejects one with an unknown block id in an edge.\n3. **Renderer light + dark** - renders `test_spec.json` in both themes; each output passes geometry validation.\n4. **Sample snapshots** - re-renders every tracked `sample_*.svg` from its spec (light + dark) and diffs it against the committed file, so a rendering change that still passes geometry validation cannot land silently. The compare is newline-normalized, so it is OS-agnostic. After an intentional rendering change, refresh the tracked samples with `python tests.py --update-samples` and commit the result.\n5. **Install dry-run** - copies the runtime files into a throwaway dir, asserts every runtime file is present, and asserts repo-only files (README, tests, fixtures) were *not* copied.\n\nTest conditions: pure Python stdlib, no external tools, runs in well under 10 s on any modern machine. Verified on the OS / Python matrix in [.github/workflows/ci.yml](.github/workflows/ci.yml) (Linux / macOS / Windows x Python 3.10 / 3.12).\n\nIf your system temp dir isn't writable (locked-down corporate Windows, sandboxed runner, etc.), tests fall back to `<repo>/tmp/` (gitignored). Override the location with the env var `HDLDIAG_TEST_TMP=/path/of/your/choice`.\n\n## Author\n\nLeonardo Capossio - [bard0 design](https://www.bard0.com) - hello@bard0.com\n\n## License\n\n[MIT](LICENSE).\n",
  "bytes": 15657,
  "sha": "ea1120aa2ebd3b87ba5260de1c67758c873ee828721d9a79528a23cdf95c9d25",
  "repo_slug": "lcapossio/hdldiagzero",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_lcapossio_hdldiagzero_hdldiagzero_afb50f87/readme"
}