← Commit history

1.2.6 (docs only): README coverage for 1.2.0-1.2.5 (baked chip thumbnail, hairline outline, orderable identity properties, hidden-property stacking) and a CHANGELOG

John Lauer ·187404c799 ·23d ago ·parent c98d7b0
8 files changed +109−7
CHANGELOG.mdadded+22
@@ -0,0 +1,22 @@+# Changelog++## 1.2.5 (2026-09-20)+- Hidden properties (Footprint, Datasheet, Description, Manufacturer, MPN, Adom Wiki, distributor numbers, `Adom_Chip_Outline`) are stacked in a column below the body, 2.54 mm apart, instead of piled at the origin. KiCad's Symbol Editor still paints hidden fields in grey, and at (0,0) they drew as one unreadable pile of text over the symbol.++## 1.2.4 (2026-09-19)+- Orderable identity. `mpn`, `distributors {mouser, digikey, lcsc}` and `wikiUrl` in the create JSON become the MPN / Mouser / DigiKey / LCSC / "Adom Wiki" symbol properties, beside Manufacturer / Datasheet / Description. adom-lbr carries them into Altium parameters and Fusion attributes.+- `create` prints a `NOT ORDERABLE YET` hint naming whichever of `mpn`, `manufacturer`, `wikiUrl` and the three distributor numbers is missing, and points at `adom-parts-search search <MPN>`.++## 1.2.3 (2026-09-19)+- Baked chip-outline polylines are written with a 0.0254 mm (1 mil) hairline stroke. KiCad draws any stroke at least one pixel wide, so the outline reads as a crisp single-pixel line at every zoom; the old 0.14 to 0.17 mm stroke smeared it.++## 1.2.2 (2026-09-19)+- `--outline-name none` (or `preferences.outlineName: "none"`): do not laser the part number under the chip when the outline already shows it, e.g. one made from a side-etched STEP. The default is `under`.++## 1.2.1 (2026-09-19)+- The `_hint:` lines `create` prints now tell the AI to check the Adom wiki first (`adom-wiki discover search --query <MPN>`): an existing component page already ships the reviewed symbol, footprint, STEP, outline cache and provenance. The generic-chip hint lists the wiki as step 0 of the ladder for getting the real body.++## 1.2.0 (2026-09-19)+- The 3D-chip thumbnail outline is baked into every IC symbol by default, as real KiCad polylines centred in the lane between the pin-name columns: the part's real outline when chip-thumbnailer has rendered `<mpn>-3d-outline-*-named.svg` (or `--outline-svg` is given), otherwise a generic isometric chip with the part name lasered on top. A hidden `Adom_Chip_Outline` property records the source. Off with `--no-chip-outline` / `preferences.chipOutline:false`; size with `--chip-size large|medium|small`.++Earlier history is in the wiki repo commit log.
Cargo.lock+1−1
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "adom-symbol"-version = "1.1.13"+version = "1.2.6" dependencies = [  "anyhow",  "clap",
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-symbol"-version = "1.2.5"+version = "1.2.6" edition = "2021" description = "Create and preview KiCad/Fusion 360 schematic symbols with interactive viewer" 
README.md+78
@@ -15,6 +15,84 @@ lasered on top. Turn it off with `--no-chip-outline` (or `preferences.chipOutlin or `chipOutline:false` in `~/.claude/skills/adom/preferences.json`); size it with `--chip-size large|medium|small`. +The source is picked in order: `--outline-svg <file>` (or `outlineSvg` in the create JSON),+then an auto-discovered `<mpn>-3d-outline-{heavy,dark,hairline,teal}-named.svg` beside `--out`,+beside the create JSON, in the cwd or in chip-fetcher's `library/<mpn>/`, then the built-in+generic chip. The icon is centred in the text-free lane between the pin-name columns; a short+2-column body is grown on the grid so a readable icon (9 mm or more) fits, and under 9 mm the+icon is left out. A hidden `Adom_Chip_Outline` property records what was baked, and `render`+sees it and does not composite a second chip on top. The stdout of `create` says which source+was used.++### Hints that send the AI to the Adom wiki first (from 1.2.1)++When a chip outline was baked, `create` ends with `_hint:` lines. The first is WIKI FIRST:+before fetching, modelling or lasering anything for the part, run+`adom-wiki discover search --query <MPN>` (and `adom-wiki discover find <MPN>`), because an+existing component page already carries the reviewed symbol, footprint, `.lbr`, the+manufacturer STEP, the outline cache (`artwork/<MPN>-thumbs.json`) and provenance;+`adom-wiki repo clone adom/<slug>` and reuse it. When the generic chip was baked, a second+hint lists where to get the real body, the wiki again first, then the manufacturer STEP,+`chip-fetcher fetch <MPN>`, or modelling it from the datasheet, followed by+`adom-chip-thumbnailer once <MPN>` and a re-run of `create`.++### `--outline-name none` (from 1.2.2)++With an un-named outline (`--outline-svg <lib>/<MPN>-3d-outline-heavy.svg`), adom-symbol+lasers the part number UNDER the chip inside the icon box; that is `--outline-name under`,+the default. When the outline comes from a side-etched STEP, where the MPN already shows on+the chip's wall, pass `--outline-name none` (or `preferences.outlineName: "none"` in the+create JSON) so the part number is not shown twice. The CLI flag wins over the create JSON.++### Hairline outline stroke (from 1.2.3)++Baked chip-outline polylines are written with a 0.0254 mm (1 mil) stroke. KiCad draws any+stroke at least one pixel wide, so the dense thumbnailer art reads as a crisp single-pixel+line at every zoom; the earlier 0.14 to 0.17 mm stroke smeared it into a blob. adom-lbr+2.44.0+ maps the same stroke to Altium's Smallest line width and to 0.0254 mm EAGLE wires,+so the hairline reaches Altium and Fusion from this one symbol.++## Orderable identity (from 1.2.4)++The BOM and CPL a fab receives with the gerbers are built from the part's identity fields,+so the create JSON carries them and `create` writes them onto the symbol as hidden properties:++| Create JSON | Symbol property |+|---|---|+| `mpn` (the orderable manufacturer part number, e.g. `VL53L5CXV0GC/1`) | `MPN` |+| `manufacturer` | `Manufacturer` |+| `datasheetUrl` | `Datasheet` |+| `description` | `Description` |+| `distributors.mouser` | `Mouser` |+| `distributors.digikey` | `DigiKey` |+| `distributors.lcsc` | `LCSC` |+| `wikiUrl` (the part's Adom wiki component page, `https://wiki.adom.inc/<owner>/<slug>`) | `Adom Wiki` |++```json+{+  "symbolName": "VL53L5CX",+  "mpn": "VL53L5CXV0GC/1",+  "manufacturer": "STMicroelectronics",+  "distributors": { "mouser": "...", "digikey": "...", "lcsc": "..." },+  "wikiUrl": "https://wiki.adom.inc/adom/vl53l5cx"+}+```++An empty `mpn` or `wikiUrl` is not written. When `mpn`, `manufacturer`, `wikiUrl` or any of the three+distributor numbers is missing, `create` prints a `_hint: NOT ORDERABLE YET` line naming+each missing field. One lookup fills the numbers: `adom-parts-search search <MPN>` (Mouser,+DigiKey and JLCPCB/LCSC with stock and price). A distributor that genuinely does not stock+the part is left out, and said so on the wiki page. adom-lbr 2.45.0+ carries these+properties into Altium parameters (plus `Supplier N` links) and Fusion attributes, and+`kicad-cli sch export bom --fields` reads them straight off a schematic.++### Hidden properties are stacked below the body (from 1.2.5)++KiCad's Symbol Editor still paints hidden fields in grey. Placed at the origin they drew as+one unreadable pile of text over the symbol. Hidden properties (Footprint, Datasheet,+Description, Manufacturer, MPN, Adom Wiki, the distributor numbers, `Adom_Chip_Outline`) are+now stacked in a column below the body, 2.54 mm apart, under the Value.+ ## Try it on any component page: the symbol-variants widget  ::adom-symbol-variants{src="/ray/ch340g/render/page.json" layout="sqg"}
VERSION+1−1
@@ -1 +1 @@-1.2.5+1.2.6
bin/adom-symbol
⋯ 1 unchanged line ⋯
package.json+2−1
@@ -1,6 +1,6 @@ {   "slug": "adom-symbol",-  "version": "1.2.5",+  "version": "1.2.6",   "type": "app",   "description": "KiCad symbol creator with interactive viewer and delivery to KiCad/Fusion 360",   "dependencies": {@@ -18,6 +18,7 @@     "uninstall.sh",     "package.json",     "README.md",+    "CHANGELOG.md",     "SKILL.md",     "docs/hero.png"   ],
page.json+4−3
@@ -1,6 +1,6 @@ {   "slug": "adom-symbol",-  "version": "1.2.5",+  "version": "1.2.6",   "type": "app",   "description": "KiCad symbol creator with interactive viewer and delivery to KiCad/Fusion 360",   "dependencies": {@@ -19,6 +19,7 @@     "uninstall.sh",     "package.json",     "README.md",+    "CHANGELOG.md",     "SKILL.md",     "docs/hero.png"   ],@@ -40,7 +41,7 @@   "org": "adom",   "updated_at": "2026-06-28T20:46:29.458Z",   "source_visibility": "public",-  "readme": "# adom-symbol\n\nStandalone Rust CLI + live app for **KiCad schematic symbols**. Generates\n`.kicad_sym` files natively in Rust, renders them as gorgeous dark-themed SVGs\nthrough the shared **service-kicad** container, and serves an AI-drivable live\nviewer with a full layout studio. No Node, no gallia, no local KiCad install.\n\n![The adom-symbol live viewer — an ADC symbol with its 3D-chip outline lasered into the body, beside the docked Layout studio](docs/screenshot-viewer.png)\n\n## What it does\n\n- **Generate** `.kicad_sym` natively in Rust — rectangle-body ICs with grouped,\n  side-sorted pins (Category A) and discrete passives derived from a KiCad\n  baseline symbol (Category B).\n- **Render** the symbol to a cropped, dark-themed SVG via service-kicad\n  (`POST /kicad/sch/export/svg`) — the same render path the chip-fetcher\n  dashboard uses, so the thumbnail and the app match exactly. The default render\n  **inlines** the part's 3D-chip **vector outline** (with the part number lasered\n  on) into the body centre as real `<polyline>`s — crisp in every renderer\n  (browser, librsvg thumbnailer, anything), not a rasterisable `<image>`.\n- **Browse + lay out** a whole chip-fetcher library in the **live viewer**: a\n  left chip-library rail (with project filters), a docked **Layout studio** for\n  the source / pin arrangement / designator placement / 3D-chip style, drag-to-\n  place labels, one-step **Undo**, and **Send to** KiCad / Fusion 360 / Altium /\n  OrCAD.\n- **Emit an outline contract** — alongside `<mpn>-symbol.svg`, `render` writes\n  `<mpn>-symbol-outline.mm.svg` + `<mpn>-symbol-outline.json` so **adom-lbr** can\n  draw the exact same chip outline onto the EAGLE/Fusion 360 symbol with **zero\n  guessing**. See [3D-chip outline contract](#3d-chip-outline-contract-for-adom-lbr).\n- **Serve** a live, AI-drivable app: the frontend stays connected to the Rust\n  server (`GET /state` poller + `POST /eval` channel), so the AI can push a new\n  symbol, hot-patch the UI, or read the console in real time.\n\n## The live viewer\n\n`adom-symbol serve` opens an interactive, AI-drivable viewer over the whole\nchip-fetcher library. The **Layout studio is always open** on the right — it's\nwhere you shape the symbol — and a collapsible chip-library rail sits on the\nleft.\n\n**Browse the library.** Every chip in the library root, with chip-fetcher's\nproject filters; ↑/↓ to step through, and each chip auto-saves the look you give\nit (per-symbol; your last-used choices fill in untouched chips).\n\n![The chip-library rail (74 chips) on the left, a symbol with its shaded 3D chip in the body, and the docked Layout studio on the right](screenshots/app-chip-rail.png)\n\n**Shape it in the Layout studio.** Pick the **source** (auto-grouped from ds2sf,\nor any manufacturer / Altium / Fusion / KiCad library variant), the pin\n**layout** (left-right or all-sides) and grouping, the **3D-chip** overlay style\n(off / shaded iso / thin / bold / blue / teal / dark) and size, where the chip\nname shows (lasered on the chip, in the symbol, both, or hidden), and then\n**Send to** a desktop EDA tool.\n\n![The shaded photoreal \"iso\" 3D chip composited into the symbol body](screenshots/app-3d-iso.png)\n\n**Place the labels — auto or by hand.** The Reference (`U?`/`Y?`) and chip-name\ndesignators don't have to overlap the body or pins. **Auto-place** centres both\nclear of everything; flip on **Manual** and each label gets a drag-outline you\ngrab and drop exactly where you want — it re-renders live and auto-saves to that\nchip. Any change (layout, 3D look, size, auto-place, a label drag) steps back\nwith **↶ Undo** or Ctrl/⌘+Z.\n\n![Manual label mode on a crystal — the Reference (Y?) and chip name (Crystal_GND24) each wrapped in a drag-outline you position by hand](screenshots/app-label-placement.png)\n\n## Install\n\n```\nadompkg install adom-symbol\n```\n\n## Quick start\n\n```bash\n# Create a symbol from structured pin JSON (stdin or --file)\nadom-symbol create --file rp2040.json --out RP2040\n\n# Preview an existing .kicad_sym as a themed viewer\nadom-symbol preview --file RP2040/RP2040.kicad_sym\n\n# Render a .kicad_sym to a themed thumbnail SVG (+ outline contract for adom-lbr)\nadom-symbol render --file RP2040/RP2040.kicad_sym --out RP2040-symbol.svg\n\n# Run the live app (AI-drivable: /state, /load, /eval, /console)\nadom-symbol serve --port 8781 --file RP2040/RP2040.kicad_sym\n```\n\nOpen the served app through the Adom proxy URL\n(`https://<slug>.adom.cloud/proxy/8781/`), never `localhost:8781` — the webview\nrenders outside the container.\n\n## CLI reference\n\n| Command | Description |\n|---|---|\n| `create --file <json> [--out <dir>]` | Generate `.kicad_sym` + SVG + viewer HTML from pin JSON |\n| `preview --file <kicad_sym> [--out <dir>]` | Render an existing symbol to a themed viewer |\n| `render --file <kicad_sym> --out <svg> [--iso <png>] [--chip-size large\\|medium\\|small]` | Render to a themed thumbnail SVG; auto-composites the 3D-chip outline + emits the outline contract |\n| `embed --file <kicad_sym> [--out <html>]` | Export a self-contained interactive HTML viewer (pan/zoom + pin info) |\n| `serve [--port 8781] [--file <kicad_sym>]` | Run the live AI-drivable viewer + layout studio |\n\n## 3D-chip outline contract (for adom-lbr)\n\nThe default `render` composites the part's **3D-chip vector outline** (white\n`heavy` style, with the part number lasered on the top face) into the symbol\nbody — sized to **0.62×** the body's smaller side, fitted from the source\n`320×320` outline canvas and centred on the body rectangle.\n\n![A symbol rendered with its 3D chip outline inlined into the body as crisp vector, the part number lasered on the top face](screenshots/app-outline-in-body.png)\n\nBecause that exact placement was previously re-guessed downstream (adom-lbr fit\nthe outline to ~0.38× of a different reference frame, so it drifted ~30% small),\n`render` now **exposes the placement** so it can be transcribed 1:1. Next to\n`<mpn>-symbol.svg` it writes:\n\n| File | What it is |\n|---|---|\n| `<mpn>-symbol-outline.mm.svg` | The outline strokes **only**, as decimated (lite) `<polyline>`s, in the **same units / origin / viewBox** as `<mpn>-symbol.svg` (mm, Y-down). A drop-in overlay; each stroke keeps the source style's real colour/width/dash (and the neon glow `<defs>`, blur scaled to mm). |\n| `<mpn>-symbol-outline.json` | A self-describing sidecar: the canonical `default_variant`, the source viewBox, segment count, and the exact transform in **both** frames — EAGLE/KiCad **Y-up** (what adom-lbr maps to) and the symbol-svg **Y-down** overlay frame. |\n\n`adom-lbr generate --symbol-art <mpn>-symbol-outline.mm.svg` detects the contract\n(via the sibling `.json`), derives the svg→EAGLE offset/flip from the two frame\ncentres, and emits the outline as layer-94 `<wire>`s — no re-fitting, no\nre-decimation, so the art lands exactly where adom-symbol drew it.\n\n> The **canonical embedded variant is `heavy`** (white `#e6edf3`, single visible\n> layer) — clean as schematic wires. The multi-layer styles (`blueprint`/`xray`\n> add hidden dashed edges, `neon` is a 2-layer glow) are deliberately avoided for\n> embedding.\n\n### Outline placement (the math `render` exposes)\n\nFor a source outline point `(px, py)` in the `320×320` canvas:\n\n```\nscale      = min(body_w, body_h) · 0.62 / 320          # mm per source unit\neagle_x    = center_x + (px − 160) · scale             # KiCad/EAGLE Y-up\neagle_y    = center_y − (py − 160) · scale             # (note the Y flip)\n```\n\n`center_x/center_y` (and the Y-down `symbol.svg`-frame equivalents) are written\nverbatim into the sidecar, so a consumer never has to reconstruct them.\n\n### The contract, proven\n\nThe emitted `.mm.svg` (recoloured magenta) placed over the live `-symbol.svg` —\ndead-centre in the body, framed by the real pins, tracing the chip body, side\npads and lasered name. Zero drift.\n\n![Magenta outline contract centered in the symbol body, framed by the pins](screenshots/outline-alignment.png)\n\nReal EAGLE `.lbr` output: **left** transcribed 1:1 from the contract (exact 0.62\nfit, centred); **right** the legacy guess — too small *and* off-centre, because\nit fit the source's ink bbox instead of the canvas.\n\n![Side-by-side EAGLE symbols: the contract fit centred vs the smaller, off-centre legacy guess](screenshots/outline-lbr-contract-vs-legacy.png)\n\n![The outline-contract JSON with placement in both coordinate frames](screenshots/outline-contract-json.png)\n\n## Architecture\n\nPure Rust. Symbol generation (`src/sym_gen.rs`, `src/discrete_gen.rs`) is a\nbyte-for-byte port of the original generator, **verified against golden files**\nin `tests/`. The only network dependency is **service-kicad** for SVG rendering\n— a lightweight proxy to the shared KiCad-10 container, so nothing installs\nKiCad locally. The live app server (`src/server.rs`) follows the Adom\napp-creator contract: `GET /state`, `POST /load`, `POST /eval` +\n`GET /eval/pending` + `POST /eval/:id/result`, `GET/POST /console`,\n`POST /shutdown`, `GET /favicon.svg`, and best-effort HD port registration.\nPer-symbol layout (including dragged label positions) persists to each chip's\n`info.json` and bakes into its `.kicad_sym` on save.\n\n## Build from source\n\nThe full source ships on the wiki app page — anyone in the community can build\nit locally:\n\n```bash\n# Fetch the source bundle from the wiki\nadompkg source adom-symbol            # downloads + unpacks the repo\n\ncargo build --release                 # standalone — only needs Rust + cargo\ncargo test --release                  # runs the golden-file parity tests\ncp target/release/adom-symbol ~/.local/bin/\n```\n\nThe only runtime dependency is network access to a service-kicad endpoint\n(`KICAD_SERVICE_API`, defaults to the shared container).\n\n## Wiki\n\nhttps://wiki.adom.inc/adom/adom-symbol\n\n## Contributing & forking — open source under the Adom org\n\n**adom-symbol** is **open source** under the **adom** org on the [Adom Wiki](https://wiki.adom.inc/adom/adom-symbol). The full source lives in this page's repo (public) — open the **Files** tab, or `adompkg source adom-symbol`. Third-party developers are welcome to modify it and contribute back.\n\n**Modify it**\n- Get the source from the Files tab (or `adompkg source adom-symbol`), make your changes, run `cargo test --release` (keep the golden tests green), and rebuild.\n\n**Contribute back to Adom — two paths**\n1. **Pull request (preferred).** The wiki runs a PR-per-page flow: propose your change on this page and the maintainer reviews + merges it — no fork needed.\n2. **Fork + breadcrumb.** Prefer your own fork or add-on? Publish it as your own wiki page, then drop a **breadcrumb on _this_ page** pointing at your fork so it's discoverable:\n   - Read existing trails: `GET https://wiki.adom.inc/api/v1/pages/adom-symbol/breadcrumbs`\n   - Attach a breadcrumb from your fork's page targeting this anchor (a short label + your slug).\n\n   The breadcrumb leaves a **linked path back here**, so **Adom's AI can auto-discover your fork** and surface it to users — the trail is followable both ways. Your fork stays yours; the original stays discoverable.\n\n## License\n\n**MIT** — © 2026 Adom Industries Inc. Open source; see [LICENSE](LICENSE). Modify, fork, and redistribute freely.\n",+  "readme": "# adom-symbol\n\nStandalone Rust CLI + live app for **KiCad schematic symbols**. Generates\n`.kicad_sym` files natively in Rust, renders them as gorgeous dark-themed SVGs\nthrough the shared **service-kicad** container, and serves an AI-drivable live\nviewer with a full layout studio. No Node, no gallia, no local KiCad install.\n\n![The adom-symbol live viewer \u2014 an ADC symbol with its 3D-chip outline lasered into the body, beside the docked Layout studio](docs/screenshot-viewer.png)\n\n## What it does\n\n- **Generate** `.kicad_sym` natively in Rust \u2014 rectangle-body ICs with grouped,\n  side-sorted pins (Category A) and discrete passives derived from a KiCad\n  baseline symbol (Category B).\n- **Render** the symbol to a cropped, dark-themed SVG via service-kicad\n  (`POST /kicad/sch/export/svg`) \u2014 the same render path the chip-fetcher\n  dashboard uses, so the thumbnail and the app match exactly. The default render\n  **inlines** the part's 3D-chip **vector outline** (with the part number lasered\n  on) into the body centre as real `<polyline>`s \u2014 crisp in every renderer\n  (browser, librsvg thumbnailer, anything), not a rasterisable `<image>`.\n- **Browse + lay out** a whole chip-fetcher library in the **live viewer**: a\n  left chip-library rail (with project filters), a docked **Layout studio** for\n  the source / pin arrangement / designator placement / 3D-chip style, drag-to-\n  place labels, one-step **Undo**, and **Send to** KiCad / Fusion 360 / Altium /\n  OrCAD.\n- **Emit an outline contract** \u2014 alongside `<mpn>-symbol.svg`, `render` writes\n  `<mpn>-symbol-outline.mm.svg` + `<mpn>-symbol-outline.json` so **adom-lbr** can\n  draw the exact same chip outline onto the EAGLE/Fusion 360 symbol with **zero\n  guessing**. See [3D-chip outline contract](#3d-chip-outline-contract-for-adom-lbr).\n- **Serve** a live, AI-drivable app: the frontend stays connected to the Rust\n  server (`GET /state` poller + `POST /eval` channel), so the AI can push a new\n  symbol, hot-patch the UI, or read the console in real time.\n\n## The live viewer\n\n`adom-symbol serve` opens an interactive, AI-drivable viewer over the whole\nchip-fetcher library. The **Layout studio is always open** on the right \u2014 it's\nwhere you shape the symbol \u2014 and a collapsible chip-library rail sits on the\nleft.\n\n**Browse the library.** Every chip in the library root, with chip-fetcher's\nproject filters; \u2191/\u2193 to step through, and each chip auto-saves the look you give\nit (per-symbol; your last-used choices fill in untouched chips).\n\n![The chip-library rail (74 chips) on the left, a symbol with its shaded 3D chip in the body, and the docked Layout studio on the right](screenshots/app-chip-rail.png)\n\n**Shape it in the Layout studio.** Pick the **source** (auto-grouped from ds2sf,\nor any manufacturer / Altium / Fusion / KiCad library variant), the pin\n**layout** (left-right or all-sides) and grouping, the **3D-chip** overlay style\n(off / shaded iso / thin / bold / blue / teal / dark) and size, where the chip\nname shows (lasered on the chip, in the symbol, both, or hidden), and then\n**Send to** a desktop EDA tool.\n\n![The shaded photoreal \"iso\" 3D chip composited into the symbol body](screenshots/app-3d-iso.png)\n\n**Place the labels \u2014 auto or by hand.** The Reference (`U?`/`Y?`) and chip-name\ndesignators don't have to overlap the body or pins. **Auto-place** centres both\nclear of everything; flip on **Manual** and each label gets a drag-outline you\ngrab and drop exactly where you want \u2014 it re-renders live and auto-saves to that\nchip. Any change (layout, 3D look, size, auto-place, a label drag) steps back\nwith **\u21b6 Undo** or Ctrl/\u2318+Z.\n\n![Manual label mode on a crystal \u2014 the Reference (Y?) and chip name (Crystal_GND24) each wrapped in a drag-outline you position by hand](screenshots/app-label-placement.png)\n\n## Install\n\n```\nadompkg install adom-symbol\n```\n\n## Quick start\n\n```bash\n# Create a symbol from structured pin JSON (stdin or --file)\nadom-symbol create --file rp2040.json --out RP2040\n\n# Preview an existing .kicad_sym as a themed viewer\nadom-symbol preview --file RP2040/RP2040.kicad_sym\n\n# Render a .kicad_sym to a themed thumbnail SVG (+ outline contract for adom-lbr)\nadom-symbol render --file RP2040/RP2040.kicad_sym --out RP2040-symbol.svg\n\n# Run the live app (AI-drivable: /state, /load, /eval, /console)\nadom-symbol serve --port 8781 --file RP2040/RP2040.kicad_sym\n```\n\nOpen the served app through the Adom proxy URL\n(`https://<slug>.adom.cloud/proxy/8781/`), never `localhost:8781` \u2014 the webview\nrenders outside the container.\n\n## CLI reference\n\n| Command | Description |\n|---|---|\n| `create --file <json> [--out <dir>]` | Generate `.kicad_sym` + SVG + viewer HTML from pin JSON |\n| `preview --file <kicad_sym> [--out <dir>]` | Render an existing symbol to a themed viewer |\n| `render --file <kicad_sym> --out <svg> [--iso <png>] [--chip-size large\\|medium\\|small]` | Render to a themed thumbnail SVG; auto-composites the 3D-chip outline + emits the outline contract |\n| `embed --file <kicad_sym> [--out <html>]` | Export a self-contained interactive HTML viewer (pan/zoom + pin info) |\n| `serve [--port 8781] [--file <kicad_sym>]` | Run the live AI-drivable viewer + layout studio |\n\n## 3D-chip outline contract (for adom-lbr)\n\nThe default `render` composites the part's **3D-chip vector outline** (white\n`heavy` style, with the part number lasered on the top face) into the symbol\nbody \u2014 sized to **0.62\u00d7** the body's smaller side, fitted from the source\n`320\u00d7320` outline canvas and centred on the body rectangle.\n\n![A symbol rendered with its 3D chip outline inlined into the body as crisp vector, the part number lasered on the top face](screenshots/app-outline-in-body.png)\n\nBecause that exact placement was previously re-guessed downstream (adom-lbr fit\nthe outline to ~0.38\u00d7 of a different reference frame, so it drifted ~30% small),\n`render` now **exposes the placement** so it can be transcribed 1:1. Next to\n`<mpn>-symbol.svg` it writes:\n\n| File | What it is |\n|---|---|\n| `<mpn>-symbol-outline.mm.svg` | The outline strokes **only**, as decimated (lite) `<polyline>`s, in the **same units / origin / viewBox** as `<mpn>-symbol.svg` (mm, Y-down). A drop-in overlay; each stroke keeps the source style's real colour/width/dash (and the neon glow `<defs>`, blur scaled to mm). |\n| `<mpn>-symbol-outline.json` | A self-describing sidecar: the canonical `default_variant`, the source viewBox, segment count, and the exact transform in **both** frames \u2014 EAGLE/KiCad **Y-up** (what adom-lbr maps to) and the symbol-svg **Y-down** overlay frame. |\n\n`adom-lbr generate --symbol-art <mpn>-symbol-outline.mm.svg` detects the contract\n(via the sibling `.json`), derives the svg\u2192EAGLE offset/flip from the two frame\ncentres, and emits the outline as layer-94 `<wire>`s \u2014 no re-fitting, no\nre-decimation, so the art lands exactly where adom-symbol drew it.\n\n> The **canonical embedded variant is `heavy`** (white `#e6edf3`, single visible\n> layer) \u2014 clean as schematic wires. The multi-layer styles (`blueprint`/`xray`\n> add hidden dashed edges, `neon` is a 2-layer glow) are deliberately avoided for\n> embedding.\n\n### Outline placement (the math `render` exposes)\n\nFor a source outline point `(px, py)` in the `320\u00d7320` canvas:\n\n```\nscale      = min(body_w, body_h) \u00b7 0.62 / 320          # mm per source unit\neagle_x    = center_x + (px \u2212 160) \u00b7 scale             # KiCad/EAGLE Y-up\neagle_y    = center_y \u2212 (py \u2212 160) \u00b7 scale             # (note the Y flip)\n```\n\n`center_x/center_y` (and the Y-down `symbol.svg`-frame equivalents) are written\nverbatim into the sidecar, so a consumer never has to reconstruct them.\n\n### The contract, proven\n\nThe emitted `.mm.svg` (recoloured magenta) placed over the live `-symbol.svg` \u2014\ndead-centre in the body, framed by the real pins, tracing the chip body, side\npads and lasered name. Zero drift.\n\n![Magenta outline contract centered in the symbol body, framed by the pins](screenshots/outline-alignment.png)\n\nReal EAGLE `.lbr` output: **left** transcribed 1:1 from the contract (exact 0.62\nfit, centred); **right** the legacy guess \u2014 too small *and* off-centre, because\nit fit the source's ink bbox instead of the canvas.\n\n![Side-by-side EAGLE symbols: the contract fit centred vs the smaller, off-centre legacy guess](screenshots/outline-lbr-contract-vs-legacy.png)\n\n![The outline-contract JSON with placement in both coordinate frames](screenshots/outline-contract-json.png)\n\n## Architecture\n\nPure Rust. Symbol generation (`src/sym_gen.rs`, `src/discrete_gen.rs`) is a\nbyte-for-byte port of the original generator, **verified against golden files**\nin `tests/`. The only network dependency is **service-kicad** for SVG rendering\n\u2014 a lightweight proxy to the shared KiCad-10 container, so nothing installs\nKiCad locally. The live app server (`src/server.rs`) follows the Adom\napp-creator contract: `GET /state`, `POST /load`, `POST /eval` +\n`GET /eval/pending` + `POST /eval/:id/result`, `GET/POST /console`,\n`POST /shutdown`, `GET /favicon.svg`, and best-effort HD port registration.\nPer-symbol layout (including dragged label positions) persists to each chip's\n`info.json` and bakes into its `.kicad_sym` on save.\n\n## Build from source\n\nThe full source ships on the wiki app page \u2014 anyone in the community can build\nit locally:\n\n```bash\n# Fetch the source bundle from the wiki\nadompkg source adom-symbol            # downloads + unpacks the repo\n\ncargo build --release                 # standalone \u2014 only needs Rust + cargo\ncargo test --release                  # runs the golden-file parity tests\ncp target/release/adom-symbol ~/.local/bin/\n```\n\nThe only runtime dependency is network access to a service-kicad endpoint\n(`KICAD_SERVICE_API`, defaults to the shared container).\n\n## Wiki\n\nhttps://wiki.adom.inc/adom/adom-symbol\n\n## Contributing & forking \u2014 open source under the Adom org\n\n**adom-symbol** is **open source** under the **adom** org on the [Adom Wiki](https://wiki.adom.inc/adom/adom-symbol). The full source lives in this page's repo (public) \u2014 open the **Files** tab, or `adompkg source adom-symbol`. Third-party developers are welcome to modify it and contribute back.\n\n**Modify it**\n- Get the source from the Files tab (or `adompkg source adom-symbol`), make your changes, run `cargo test --release` (keep the golden tests green), and rebuild.\n\n**Contribute back to Adom \u2014 two paths**\n1. **Pull request (preferred).** The wiki runs a PR-per-page flow: propose your change on this page and the maintainer reviews + merges it \u2014 no fork needed.\n2. **Fork + breadcrumb.** Prefer your own fork or add-on? Publish it as your own wiki page, then drop a **breadcrumb on _this_ page** pointing at your fork so it's discoverable:\n   - Read existing trails: `GET https://wiki.adom.inc/api/v1/pages/adom-symbol/breadcrumbs`\n   - Attach a breadcrumb from your fork's page targeting this anchor (a short label + your slug).\n\n   The breadcrumb leaves a **linked path back here**, so **Adom's AI can auto-discover your fork** and surface it to users \u2014 the trail is followable both ways. Your fork stays yours; the original stays discoverable.\n\n## License\n\n**MIT** \u2014 \u00a9 2026 Adom Industries Inc. Open source; see [LICENSE](LICENSE). Modify, fork, and redistribute freely.\n",   "discovery_pitch": "Generate, preview, and lay out KiCad/EAGLE schematic symbols in an interactive studio, then deliver them straight to KiCad, Fusion 360, Altium, or OrCAD.",   "discovery_triggers": [     "create a kicad symbol",@@ -67,4 +68,4 @@       "prompt": "open my RP2040.kicad_sym in the interactive symbol viewer"     }   ]-}\ No newline at end of file+}