|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## What this project is |
| 6 | + |
| 7 | +WireViz is a Python CLI tool that turns YAML descriptions of cables, wiring harnesses, and connector pinouts into rendered diagrams (SVG/PNG/HTML/GraphViz) and an auto-generated Bill of Materials (TSV). Input is a single YAML file with `connectors`, `cables`, and `connections` sections; output is rendered by piping a generated GraphViz `.gv` file through `dot`. |
| 8 | + |
| 9 | +This repo is the **upstream Python CLI**. A separate GUI front-end is being built in a sibling repo (`wireviz-gui`, not yet present in this working tree) that will eventually wrap or reuse this codebase. **All core parsing, harness-modeling, and rendering work happens here first.** Treat this repo as the engine; the GUI consumes its outputs (and likely its `wireviz.parse()` Python API). Avoid CLI-only assumptions in core modules — anything outside `wv_cli.py` should remain library-callable so the GUI can drive it programmatically. |
| 10 | + |
| 11 | +## Commands |
| 12 | + |
| 13 | +WireViz has **no automated test suite**. The de-facto regression check is rebuilding the examples and diffing the output. |
| 14 | + |
| 15 | +```bash |
| 16 | +# Install for development (from repo root) |
| 17 | +pip install -e . |
| 18 | + |
| 19 | +# Run the CLI on a YAML file (produces .gv .svg .png .html .bom.tsv next to input) |
| 20 | +wireviz path/to/file.yml |
| 21 | + |
| 22 | +# Limit output formats: g=gv h=html p=png s=svg t=tsv |
| 23 | +wireviz -f hps path/to/file.yml |
| 24 | + |
| 25 | +# Rebuild every demo, example, and tutorial (must cd into src/wireviz) |
| 26 | +cd src/wireviz && python build_examples.py |
| 27 | + |
| 28 | +# Diff regenerated outputs against the last commit (regression check after code changes) |
| 29 | +cd src/wireviz && python build_examples.py compare |
| 30 | + |
| 31 | +# Same, but also diff the .gv GraphViz source |
| 32 | +cd src/wireviz && python build_examples.py compare -c |
| 33 | + |
| 34 | +# Restore generated files from git before committing (avoid committing rebuilt artifacts in PRs) |
| 35 | +cd src/wireviz && python build_examples.py restore |
| 36 | + |
| 37 | +# Limit any of the above to a subset |
| 38 | +cd src/wireviz && python build_examples.py compare -g examples tutorial demos |
| 39 | +``` |
| 40 | + |
| 41 | +GraphViz must be installed as a system dep (`dot -V`). Code is formatted with `black` + `isort` (`isort` profile is `black`, configured in `pyproject.toml`). |
| 42 | + |
| 43 | +CI (`.github/workflows/`) runs only `build_examples.py` across Python 3.7–3.12 — there is no `pytest`. If you add real tests, also wire them into CI. |
| 44 | + |
| 45 | +## Architecture |
| 46 | + |
| 47 | +The pipeline is **YAML → Harness object graph → GraphViz `.gv` → rendered SVG/PNG (+ embedded HTML) + BOM TSV**. All modules live in `src/wireviz/`. |
| 48 | + |
| 49 | +### Entry points |
| 50 | + |
| 51 | +- **`wv_cli.py`** — Click CLI. Reads files, handles `--prepend`, `--format`, `--output-dir`, `--output-name`, then delegates to `wireviz.parse()`. Thin wrapper; do not put logic here that the GUI would also need. |
| 52 | +- **`wireviz.py`** — `parse()` is the real public API. Accepts a path, YAML string, or pre-parsed dict; writes any combination of `gv/svg/png/html/tsv` files and/or returns PNG/SVG bytes or the `Harness` object. The GUI will most likely call this directly. Keep its signature stable. |
| 53 | +- **`build_examples.py`** — standalone script (run via `cd src/wireviz && python build_examples.py`, **not** as a module). Walks `examples/`, `tutorial/`, `demos/`, regenerates artifacts, and supports `compare`/`clean`/`restore` against git. Uses `sys.path` hackery to find the `wireviz` package — that's why it must be invoked from `src/wireviz/`. |
| 54 | + |
| 55 | +### Core model |
| 56 | + |
| 57 | +- **`DataClasses.py`** — the typed schema for everything the YAML can express: `Connector`, `Cable`, `Image`, `Options`, `Metadata`, `Tweak`, `MateComponent`/`MatePin`, plus type aliases (`Pin`, `Wire`, `Designator`, `Side`, color types). Adding a new YAML field almost always starts here. |
| 58 | +- **`Harness.py`** — the in-memory harness graph. Holds dicts of connectors, cables, and a list of connections; provides `connect()`, BOM aggregation, and the GraphViz emission that produces the diagram. This is where most diagram-layout decisions live. |
| 59 | +- **`wireviz.py`** (the `parse()` function below the API surface) — orchestrates: parses YAML, resolves the connection-set syntax, expands templates (the `Template.designator` separator semantics live here), builds the `Harness`, then calls into rendering. |
| 60 | + |
| 61 | +### Rendering helpers |
| 62 | + |
| 63 | +- **`wv_gv_html.py`** — builds the HTML-style table labels GraphViz uses for nodes (connectors, cables). All visual structure of a node is assembled here as nested HTML. |
| 64 | +- **`wv_html.py`** + `templates/*.html` — wraps the rendered SVG and BOM into a standalone HTML page using simple string-template substitution (no Jinja). |
| 65 | +- **`svgembed.py`** — inlines referenced raster images into the SVG so the SVG/HTML output is self-contained. |
| 66 | +- **`wv_bom.py`** — BOM aggregation/dedup logic (`mini_bom_mode`, part-number handling, additional components). Reused for both the standalone `.bom.tsv` and the BOM table embedded in HTML. |
| 67 | +- **`wv_colors.py`** — IEC 60757 color codes, color-scheme generators (DIN 47100, 25-pair, TIA/EIA 568), `ColorMode` (SHORT / FULL / HEX, upper/lower). |
| 68 | +- **`wv_helper.py`** — shared utilities: `awg_equiv`/`mm2_equiv` gauge conversion, `expand` (range syntax), `tuplelist2tsv`, `smart_file_resolve` (image-path resolution against the input dir + `--prepend` dirs). |
| 69 | + |
| 70 | +### Cross-cutting things to know |
| 71 | + |
| 72 | +- **YAML connections syntax is positional.** A connection set is a list that *must* alternate between connector references and cable/arrow references, with pin/wire counts that match. The validation lives in `wireviz.parse()` (`check_type`, `expected_type`); errors here usually mean malformed connection lists, not a code bug. |
| 73 | +- **`--prepend` files** are concatenated before the main YAML so users can share connector/cable libraries. Image paths from prepend files are added to `image_paths` so relative `image: src:` references still resolve. |
| 74 | +- **The `tweak` section** (`DataClasses.Tweak`) lets users override or append raw GraphViz attributes on the generated `.gv`. It runs after normal emission — keep it that way; don't bake tweak handling into the model layer. |
| 75 | +- **Backwards-compat shims**: `OLD_CONNECTOR_ATTR` in `Harness.py` maps deprecated keys (`pinout`, `pinnumbers`, `autogenerate`) to friendly errors. Add new deprecations there rather than silently accepting old keys. |
| 76 | +- **Generated artifacts (`*.gv`, `*.svg`, `*.png`, `*.html`, `*.bom.tsv` under `examples/`, `tutorial/`) are checked into git.** Don't include incidental rebuilds in PRs — the project policy (per `CONTRIBUTING.md`) is that maintainers rebuild on merge. Use `build_examples.py restore` before committing. |
| 77 | + |
| 78 | +## Contribution conventions |
| 79 | + |
| 80 | +- Base branch for PRs is `dev`, not `master` (`master` only receives release merges). |
| 81 | +- Format with `isort` then `black` before committing. |
| 82 | +- Docstrings follow Google style. |
| 83 | +- If a change touches YAML syntax, update `docs/syntax.md` in the same PR. |
0 commit comments