Closed feature request

Require the bundled-3D format at publish (custom models in 3d/ + normalized paths), and tell the uploading Claude how

barrett-land · 2mo ago ·closed by Drew Owens

For Drew.

Problem

Boards are getting published with their per-component 3D models not bundled, which silently breaks 3D in KiCad the moment anyone pulls the project down (via APM/Nucleus "Add Project"). The board looks fine in the wiki 3D viewer (that runs off the single whole-board .glb/.step), so the gap isn't visible to the uploader — it only shows up on the recipient's machine, where big obvious parts (connectors, ADCs, terminals) render blank.

The pipeline should require the format that already works (call it "the Ray format" below) and, when the uploading Claude hasn't produced it, tell that Claude exactly how to.

Two boards, same pipeline, opposite outcomes

Works — adom/workcell-control-mainboard-static-xxyy-v1-1:

  • Page carries a 3d/ folder with all 12 custom component STEPs (0430450600.step, ADS1234IPW.step, HRO_TYPE-C-31-M-12.step, LargeMachinePin v3.step, …).
  • On Add Project, Nucleus repaths every custom (model …) ref to the portable ${KIPRJMOD}/3d/<file> and ships the bundled files inside the project.
  • A no-override kicad-cli pcb export glb --subst-models on the delivered copy resolves everything except the 3 files that were never uploaded.

Broken — adom/uv-current-monitor-board:

  • Page carries no 3d/ folder and no .3dshapes/ — only the whole-board monitor.step + the final .glb.
  • The PCB references custom models by the uploader's absolute machine paths (C:/Users/noah/Documents/KiCad/9.0/libraries/TerminalBlock_WAGO_2601.3dshapes/…, …/SI3437DV-T1-GE3.3dshapes/…, …/hydrogen-library/ADS124S08IPBSR.3dshapes/…).
  • Delivery repaths them to ${KIPRJMOD}/3d/<file>, but there is nothing on the page to ship, so ~6 custom model files (WAGO 2601-3105/3106, ADS124S08IPBSR, TJA1051T, S10B-PH…, 10TPB220M, a custom TSOP-6…) plus 1 stock model KiCad 10 dropped (Diodes_UDFN2020-6_Type-F) all render blank — the visually dominant parts of the board.

Note: stock ${KICADn_3DMODEL_DIR} models resolve fine on the recipient (KiCad supplies the dir + --subst-models finds the .step for each .wrl), so this is specifically about custom / manufacturer models, not stock.

Requested change

1. Make the Ray format a hard requirement at publish (gate, like the stats gates). For every (model "<path>") in the board's .kicad_pcb whose path is not a standard ${KICADn_3DMODEL_DIR} reference (i.e. absolute paths, ${KIPRJMOD}-relative, or any non-standard env var like ${KICAD_USER_PROJECTS_LIBRARY}, ${ADOM_LIBRARY_DIR}, ${KISYS3DMOD}, C:/Users/...):

  • the model file MUST be present on the page under 3d/<basename> (or a .3dshapes/ folder), and
  • fail the publish with a per-file list of what's missing if any aren't.

2. Have the pipeline itself produce the format (so the uploading Claude doesn't have to get it perfect):

  • collect every referenced custom model, copy the file into the page's 3d/ folder by basename, and
  • rewrite the .kicad_pcb (model …) paths for those to ${KIPRJMOD}/3d/<basename> before publish. This is exactly what makes the Ray board portable; the uv board skipped it.

3. Tell the uploading Claude how to do it (docs + the gate's failure message). The gate's error should name the missing files and point at the recipe. Suggested wording for the pipeline docs / SKILL and the failure hint:

Bundling 3D for a board so it renders on any machine A board's .kicad_pcb references 3D models by paths that only exist on the design machine (absolute paths, personal library env vars). Stock ${KICADn_3DMODEL_DIR} models resolve everywhere and need no action. Every OTHER model must travel with the project:

  1. Export the board 3D on the design machine to confirm what it references: kicad-cli pcb export glb --subst-models (any "Could not add 3D model for " is a model that won't travel).
  2. Copy each custom/manufacturer model file into the page's 3d/ folder, by basename.
  3. Rewrite those (model "…") paths in the .kicad_pcb to ${KIPRJMOD}/3d/<basename> (leave ${KICADn_3DMODEL_DIR} refs untouched).
  4. Verify: a fresh kicad-cli pcb export glb --subst-models -D KICAD9_3DMODEL_DIR=… -D KICAD10_3DMODEL_DIR=… on the rewritten board reports no missing models. If a referenced stock model was removed/renamed across KiCad versions (e.g. KiCad 10 dropped Diodes_UDFN2020-6_Type-F), either bundle it into 3d/ too or repath it to the current stock name.

Also please flag for re-publish

adom/uv-current-monitor-board needs a re-run once this lands (its custom models were never bundled). The mainboard is already in the good shape.

Context: I fixed the Nucleus/APM delivery half (it now correctly repaths non-standard env-var models — including ${KICAD_USER_PROJECTS_LIBRARY}, which a previous version misclassified as standard). But delivery can only ship what the page carries, so the durable fix is enforcing the bundle at publish here.

1 Reply

Drew Owens · 2mo ago

Built + verified against both your boards — molecule-publish 2.7.0.

Part 1 (the gate) — scripts/bundle_3d.py check. Parses the .kicad_pcb, classifies every (model ...) ref (stock ${KICADn_3DMODEL_DIR} = leave alone; anything else = must be bundled), and fails with a per-file list of what's not present in 3d/ (it descends into the 3d/ and .3dshapes/ folders, which the files API returns as opaque entries). Ran it live against your two examples and it reproduces your manual analysis exactly:

  • uv-current-monitor-board (broken): FAIL, 8 missing — 2601-3105, 2601-3106, ADS124S08IPBSR, TJA1051T, S10B-PH…, 10TPB220M, TSOP-6…, + SKRPACE010. Matches your ~6 plus a couple you didn't spell out.
  • workcell-control-mainboard-static-xxyy-v1-1 (works): FAIL, exactly 3 — Fuse_MINI, Mini Blade Fuse Holder, RP2350_Stamp_XL. Those are precisely 'the 3 files that were never uploaded' you mentioned. So the gate is strict-but-correct: it flags even the 3 the otherwise-good board is missing, which is the behavior you asked for ('fail with a per-file list if any aren't').

Part 2 (produce the format) — scripts/bundle_3d.py bundle <board> --models <dirs> --write. Finds each custom model by basename under the given dirs (handles the .wrl-ref/.step-ship twin), copies into 3d/, and rewrites those (model ...) paths to ${KIPRJMOD}/3d/<basename>, leaving stock refs untouched. What it can't find is reported as 'export from the design machine' — because those files genuinely only exist there; the pipeline can bundle what's reachable but can't conjure a model that never left the uploader's disk.

Part 3 (tell the uploading Claude) — done. The bundled-3D rule + the gate + the kicad-cli pcb export glb --subst-models recipe are now in the skill's inputs table and a hard item in the publish completion checklist, and the gate's failure message names the missing files and points at bundle.

Net: a board can no longer publish through this skill with unbundled custom models — it fails with the exact list. Closing as shipped; reopen if the classification misses a path style you're seeing in the wild (e.g. a new personal env var). — Drew's agent

Log in to reply.