Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Diptrace Board Build

ASecurity

Complete headless DipTrace board build pipeline extracted from proven builds (attiny85-arduino-clone 3772 LOC + i2c-level-shifter 532 LOC + dut-controller-reva). Covers LCSC sourcing → schematic generation → visual wiring → nativeize → PCB placement/routing → pours/silk → SVG preview → native DRC verification. Use when building any new board.

23 stars
0 votes
0 copies
1 views
Added 9/19/2026
documentationpythongonodeawsdebugginggitapidocumentation

Works with

terminalapimcp

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add fireostendere/mcp_diptrace --skill diptrace-board-build --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Diptrace Board Build?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Diptrace Board Build
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/fireostendere-diptrace-board-build/badge)](https://www.skillsdirectory.com/skills/fireostendere-diptrace-board-build)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: diptrace-board-build
description: >
  Complete headless DipTrace board build pipeline extracted from proven
  builds (attiny85-arduino-clone 3772 LOC + i2c-level-shifter 532 LOC +
  dut-controller-reva). Covers LCSC sourcing → schematic generation →
  visual wiring → nativeize → PCB placement/routing → pours/silk → SVG
  preview → native DRC verification. Use when building any new board.
---

# DipTrace Board Build Pipeline

## The One Rule

`build_schematic_document()` / `build_pcb_document()` produce XML that
DipTrace 5.3 CANNOT parse (silent hang). Every generated file MUST pass
through nativeization before opening in the editor.

## Architecture Overview

```
Phase 0: SOURCE          LCSC/EasyEDA → vendor/*.json → *.elixml
Phase 1: CONNECTIVITY    Builder class → PlacePart + ConnectPins
Phase 2: VISUAL WIRING   Ground symbols, Net Ports, Wires, Labels
Phase 3: NATIVEIZE       Transplant content → native template → opens in DipTrace
Phase 4: PCB SYNC        build_sync_plan → ComponentSyncMapping → placement
Phase 5: ROUTING         Priority batches → plan_pcb_routes → AddTraceOperation
Phase 6: FINISH          Pours + stitching → sanitize pads → silkscreen
Phase 7: VERIFY          ERC/DRC → SVG preview → native gate11
```

## Phase 0: Source Components

### Resolution order (house rule)
1. DipTrace installed catalog (`query_builtin_library_catalog`)
2. LCSC/EasyEDA exact MPN match
3. Custom-drawn only after both documented zero matches

### LCSC fetch pattern
```python
from diptrace_mcp.pipeline import lcsc_fetch
result = lcsc_fetch("ESP32-S3-MINI-1U-N8", "vendor/")
# Returns: code, mpn, package, pins, pads, json_path, datasheet_path
```

Fallback chain for MPN→C-code resolution:
1. DuckDuckGo HTML scrape: `html.duckduckgo.com/html/?q=<MPN>+lcsc`
2. JLCPCB parts API: POST `selectSmtComponentList`
3. Manual web search

### JSON → .elixml conversion rules

EasyEDA geometry:
- Units are 10 mil (0.254 mm); Y grows UP; DipTrace Y grows DOWN
- Symbol pins: `P~show~0~<number>~<x>~<y>~<rotation>~<id>`
- Pin names: scan `^^` sections, find `<value>~start/end~~~#color`
- Body rect: `R~<x>~<y>~...~<w>~<h>` or synthesize from PL/PG bbox
- Footprint pads: `PAD~<shape>~x~y~w~h~layer~net~number~hole_r~points~angle`
  - Shape ∈ {RECT, POLYGON, OVAL, ELLIPSE, CIRCLE}; POLY = use declared w/h
- Silk tracks: `TRACK~<width>~<layer>~<net>~points`

Critical transforms:
- **Pad ordering**: DipTrace sync maps pins↔pads POSITIONALLY. Pattern pads
  MUST be sorted to match symbol pin sequence exactly.
- **Merged pads**: "A1B12" covers two connector legs. Either split into two
  half-width pads OR renumber to integers with alias JSON.
- **Duplicate pad numbers** (ESP32 thermal grid "61"×9): merge into one pad
  with union bounding box.
- **Alphanumeric pad numbers**: DipTrace sync resolves by numeric Id fallback;
  renumber all non-digit pads sequentially in pin order + save alias map.
- **Zero-length pins**: nearest-edge body synthesis can produce length=0;
  clamp to ≥0.5mm.
- **ElectricType**: valid values are Input, Output, Bidirectional, Power,
  Passive. Unknown values may hang Schematic.exe.

## Phase 1: Schematic Connectivity

Use a Builder class pattern (see dut-controller-reva builder):

```python
class Builder:
    def part(self, stem_style, refdes, value, sheet, x, y):
        # First embed includes library_component_xml/pattern_xml/pad_style_xml
        # Subsequent placements reference the emitted style name only
        ...

    def nets(self, table):
        # table: {net_name: [(refdes, pad_number), ...]}
        # Translates pad numbers through alias if needed
        ...
```

Key gotchas:
- `_component_definitions()` renames styles to CompTypeN; track alias mapping
- Pad numbers must be unique per component (sync requirement)
- Assert `assigned ∪ no_connect == all_pins` before writing

## Phase 2: Visual Wiring

Without wires, DipTrace shows floating symbols. Three approaches:

### A. Ground Symbols + Net Ports (attiny85 pattern — BEST quality)

From `layout_and_wire.py`:

1. **`add_ground_symbols(document, groups)`** — places GND port symbols
   near ground pin clusters. Each group: (sheet, ((ref,pin),...), terminal_xy).
   Uses GROUND_LIBRARY_INDEX from installed Net Ports library.
   Sets DNP=Y on symbols so they don't appear in BOM.

2. **`add_named_net_ports(document, labels, specs)`** — places power ports
   (+3V3, VBUS) and named signal ports (Port_In/Port_Out). Labels are
   (net_name, sheet, terminal_xy). Port library index depends on net name
   length: `28 + min(max(len(net),1), 7)` for input, `36 + ...` for output.

3. **`wire(index, net, sheet, start, end, *middle_waypoints)`** — creates
   WireSpec connecting two pins via explicit waypoints. L-shaped paths.

4. **`port(index, net, sheet, key, length=7.62)`** — creates a short stub
   wire from a pin extending outward (length along pin direction), ending
   at a free endpoint where a label is placed.

5. **`append_wires(document, operations)`** — writes Wire elements into
   Nets/Net/Wires with proper Connected1/2, Object1/2, SubObject1/2 attrs.

6. **Quality checks** (assert before writing):
   - `assert_pin_escape(spec, index)` — first segment exits along pin direction
   - `body_intersections(points, sheet, boxes)` — no wire crosses a component body
   - `unrelated_pin_hits(spec, stubs, net_by_pin)` — no wire touches foreign pin
   - `crossing_count(spec, planned)` — no wire crossings on same sheet

7. **`append_overview(document)`** — draws SYSTEM_OVERVIEW sheet with
   functional blocks, cross-sheet signal lines, labels. Documentation only,
   no electrical connectivity.

8. **`annotate_rotated_parts(document)`** — replaces auto-placed RefDes/Value
   markings with manually positioned text shapes for rotated components.

9. **`center_sheet_content(document)`** — computes content bounding box per
   sheet, shifts all elements to center within page bounds minus margins.
   Asserts content fits inside page after centering.

### B. Simple Wire Chaining (my wire_schematic.py)

For large boards where manual wire specification is impractical:
- Compute absolute pin positions from library data (`compute_endpoints()`)
- Greedy nearest-neighbour chaining per net per sheet
- L-shaped paths between consecutive endpoints
- Cross-sheet pins get skipped (caller should add net labels separately)

Generated 92 wires for Rev.A (178 parts, 144 nets).

### C. Net Labels Only (minimal viable)

Place text annotations near pins showing their net name. No wires drawn.
Fastest but least readable.

## Phase 3: Nativeize

```python
from diptrace_mcp.pipeline import nativeize_document
nativeize_document(
    input_path="board.dchxml",
    template_path="proven-native.dchxml",
    output_path="board-native.dchxml",
)
```

The script `nativeize_reva.py` shows the full implementation:
- Clears template Library containers, grafts our PadStyles/Patterns/Components
- Clears Schematic/Components and Nets, grafts ours
- Clones Sheet elements for multi-sheet designs
- Forces Units="mm" on root and both Library levels
- Sets SheetWidth/SheetHeight (A4 landscape = 297×210)

Templates proven to work:
- `i2c-level-shifter-module.dchxml` — schematic (headless-built, opens clean)
- `attiny85-arduino-clone-pcb.dipxml` — PCB (native gate11-saved)

## Phase 4: PCB Sync + Placement

Follow attiny85 `build_pcb.py::build()`:

```python
physical = strip_net_ports(schematic)  # keep only Parts with Pattern refs
board = build_pcb_document(PcbScaffold(width_mm=W, height_mm=H, ...))
sync = build_sync_plan(physical, board, mappings=[ComponentSyncMapping(...)],
                        pattern_documents=[physical])
placed = apply_semantic_operations(board, [sync.operation]).document
```

Key patterns:
- **Pad renumbering**: DipTrace writes multi-pad nets as "6@"; sync requires
  unique numbers. Rename then tie to GND post-sync via direct XML injection.
- **Markings block**: Native Pcb.exe defaults RefDes to SilkAlign="Auto" with
  3mm font that lands on pads. Inject explicit Markings block:
  ```xml
  <Markings>
    <CompRotate>N</CompRotate>
    <FontVector>Y</FontVector><FontSize>1.2</FontSize>
    <RefDesGlobal SilkShow="Show" SilkAlign="Top"/>
  </Markings>
  ```
- **Route keepout**: inject Rectangle shapes with Layer="Route Keepout"
  between critical pins (e.g., switching regulator legs).
- **Manual pre-routes**: place critical traces BEFORE autorouter using
  `AddTraceOperation` with explicit waypoints. These become obstacles that
  constrain subsequent automatic routing.

## Phase 5: Routing

Priority batch ordering (from attiny85):

```python
groups = [
    (["TPS_FB"], ["Top"]),           # regulator feedback
    (["VBUS"], ["Top"]),              # power trunk
    (["USB_D-"], layers),             # diff pairs
    (["USB_D+"], layers),
    (["+3V3"], power_layers),         # rail
    *([net], layers for signal_nets), # digital signals
    (["GND"], bottom_layers),         # ground last
]
```

Router config (attiny85 proven values):
```python
PCBRouterConfig(
    grid_mm=0.125,
    clearance_mm=0.13,
    max_nodes=1_000_000,        # node cap binds before wall clock
    route_time_budget_ms=900_000,  # pure runaway guard (~300s worst case)
    max_vias_per_connection=2,
    via_cost=2.0,
    max_detour=12,
    avoid_component_bodies=False,
    allow_via_in_pad=False,
    max_ripup_attempts=3,
    allow_component_moves=False,
    placement=PCBPlacementV2Config(grid_mm=0.5, search_radius_steps=6),
)
```

**Critical**: node cap must bind before time budget, else machine load
flips results run-to-run. Measure worst-case nodes, set budget accordingly.

For boards >100mm: increase grid to 0.25–0.5mm and budgets proportionally.

## Phase 6: Finishing

### Pad sanitization
EasyEDA copper often exceeds 0.13mm rule at fine pitches. Shrink width to
(min_neighbour_distance − 0.35mm). See `sanitize_pads()` in Rev.A builder.

### Pours + stitching
```python
add_copper_pours(doc, net="GND", layers=("Top","Bottom"),
                  clearance_mm=0.22, board_clearance_mm=0.3,
                  stitch_pitch_mm=4.0, stitch_edge_mm=1.0)
```

Attiny85 final pour clearance was 0.22mm (rule was 0.13 but native raster
needed margin). Stitch pitch 4.0mm for large boards, 2.0mm for small.

### Silkscreen
```python
doc = hide_assembly_markings(doc)
plan = plan_silkscreen(build_snapshot(doc),
                        SilkscreenPlanConfig(clearance=0.15, search_steps=20))
doc = apply_semantic_operations(doc, silk.operations).document
```

Also hide Name/Value markings on ICs (keep RefDes visible only).

## Phase 7: Verification

| Gate | Tool | Pass criteria |
|---|---|---|
| ERC | `run_erc(path=...)` | 0 findings |
| Connectivity | `run_connectivity_check(path=...)` | 0 findings |
| Headless QC | `review_pcb_quality(snapshot)` | hard_error_count == 0 |
| Native roundtrip | `headless_gui roundtrip --editor schematic` | ok=true |
| Native DRC | `diptrace_native_gate11.py` | errors = fab-tolerance only |
| Visual | `render_board_svg(pcb_path)` | inspect manually |

## Debugging patterns

| Symptom | Diagnosis |
|---|---|
| DipTrace hangs on open | Missing standard sections → nativeize |
| Components off-page | Units mismatch → force mm in nativeize |
| Router produces 0 ops | Node budget exhausted → increase budgets |
| Trace violates clearance | Check obstacle identity via exc.object_ids |
| Sync fails "Cannot resolve pad" | Pattern pad order ≠ symbol pin order |
| Duplicate pad number error | Merge thermal grids, renumber shield tabs |
| RawTreeSnapshot.compile mismatch | Capture BEFORE mutation, compile AFTER |
| Wires not visible in schematic | ConnectPins ≠ AddWire; need both |

## Utility function reference

All from `attiny85-arduino-clone/layout_and_wire.py` unless noted:

| Function | Purpose |
|---|---|
| `endpoints(doc)` | Map net→absolute pin positions |
| `endpoint_index(by_net)` | (refdes,pin)→Endpoint lookup |
| `component_boxes(doc)` | refdes→(sheet,x0,y0,x1,y1) |
| `transform_local(part, x, y)` | Rotate local→global coords |
| `pin_point(index, key)` | Absolute position of a pin endpoint |
| `wire(index, ...)` | Create WireSpec between two points |
| `port(index, ...)` | Short stub wire + label point |
| `add_ground_symbols(doc, groups)` | Place GND symbols |
| `add_named_net_ports(doc, labels, specs)` | Place net port symbols |
| `append_wires(doc, ops)` | Write Wire elements to XML |
| `assert_pin_escape(spec, index)` | Validate pin exit direction |
| `body_intersections(pts, sheet, boxes)` | Wire vs body collision check |
| `crossing_count(spec, planned)` | Wire crossing count |
| `append_overview(doc)` | Draw SYSTEM_OVERVIEW blocks |
| `annotate_rotated_parts(doc)` | Reposition rotated component labels |
| `center_sheet_content(doc)` | Center content within page bounds |
| `content_bounds(doc, sheet)` | Content bbox per sheet |
| `clean_visuals(raw_bytes)` | Strip generated ports, reset markings |
| `ensure_overview_sheet(root)` | Create overview sheet if missing |
| `render_board_svg(path)` | SVG Top/Bottom preview (Rev.A) |
| `sanitize_pads()` | Shrink EasyEDA copper widths (Rev.A) |

Attribution

fireostenderefireostendere
View sourceMore from fireostendere →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Context Fundamentals

Understand the components, mechanics, and constraints of context in agent systems. Use when designing agent architectures, debugging context-related failures, or optimizing context usage.

179001 votes

release-notes

Draft release notes and changelog entries from git history or merged PRs between two refs (tags/SHAs/branches), including breaking changes, migrations, and upgrade steps. Use when the user asks for release notes, changelog updates, or a GitHub Release draft.

1301 votes

docs-style-guide

Documentation style guide enforcer by @planetabhi. Applies and reviews the writing style guide when authoring or editing product documentation and tutorials. Use to check prose for voice, tense, word choice, inclusive language, formatting, code block, UI, Markdown, and number/date conventions.

11 votes

Caveman Help

Quick-reference card for caveman modes, skills and commands. Trigger: /caveman-help or "caveman help".

1066600 votes

How It Works

Explain how claude-mem captures observations, when memory injection kicks in, and where data lives. Use when the user asks "how does claude-mem work?" or "what is this thing doing?".

942310 votes
View all in documentation →