molecule-publish
Public Made by Adomby adom
Publish molecules AND generic boards to the Adom wiki - one publisher, two shapes: OCCT conversion (molecule mode with stats gates, or plain for boards), component packaging, adom-wiki publish, APM render assets + component dependencies. Companion to adom-molecule-import.
Fabrication sources
Every new KiCad, Fusion or Altium molecule export includes <slug>-fab.zip
and export.json. Make them from the same saved board revision as the STEP.
Finish source edits, including custom-model path rewrites, before exporting.
Use a fresh folder per export so old files cannot enter a new bundle.
The zip contains both sides' copper, solder mask and silkscreen, the actual board outline, and Excellon drill files. Keep plated and unplated drills separate where the exporter supports it; record mixed drills honestly. Keep the original file bytes and names inside the zip. Optional inner copper, paste and Gerber job files may travel too. Preserve silk PNGs while the current converter still consumes them.
export.json uses the existing adom.export/1 contract from Fusion PR #17:
tool,toolVersion,exporter,exporterVersion: actual producers.files[]: relative path, role, byte count and SHA-256 for the STEP, saved board, schematic sheets and every additional source handed to publishing.- The
fab_zipfile hasentries[], each with its relative path inside the zip, role, byte count and SHA-256. Nested entries avoid confusing archive members with real page paths. - Layer roles:
copper_top,copper_bottom,mask_top,mask_bottom,silk_top,silk_bottom,outline; drill roles:drill_plated,drill_unplated,drill_mixed; optionalpaste_top,paste_bottom,copper_inner_1(and subsequent inner layers),gerber_jobandother. - Source roles:
step,board_kicad_pcb,board_eagle_brd,board_altium_pcbdoc,schematic,project, and descriptive roles for optional sources (for examplefusion_archive,usdz,bom,cpl). stackup: knownthicknessMm,copperLayers,maskColorandsilkColorbytop/bottom, andfinish. Unknown values stay null or absent; never turn a viewer's default into claimed design data.gerbers.includedis true.drill.platingsayssplitormixed. Exporters may also preserveorigin,outline,exportedAtand their own provenance. A historical backfill carriesbackfilland its originaltier; it must never claim to be a fresh native EDA export.
The helper in this package is Python 3.9+ with no third-party dependencies. Run it from the package directory, with the export folder as its argument:
python3 scripts/fab_bundle.py create /path/to/bundle --slug my-board \
--fab /path/to/fresh-gerbers --tool KiCad --tool-version 10.0.3 \
--exporter adom/kicad-export-molecule --exporter-version 1.2.0 \
--source step=Board.step --source board_kicad_pcb=Board.kicad_pcb \
--source schematic=Board.kicad_sch --source project=Board.kicad_pro \
--stackup /path/to/known-stackup.json
python3 scripts/fab_bundle.py check /path/to/bundle --slug my-board
Use the versions actually installed, not the example values. --fab also
accepts an EDA-produced zip. --stackup is optional; pass the data the EDA
provides. Repeat --source for every exported source, including every
schematic sheet. The helper writes the canonical zip name without changing
its members' bytes. It refuses missing layers, a blank outline, missing drill
data and changed hashes. It does not prove alignment or validate the circuit;
the existing conversion and manufacturing checks still apply.
For a bridge-produced record, verify it before any packaging rename. If the bridge used a design stem instead of the wiki slug, use a fresh staging folder and regenerate the record against the final filenames. Never rename a recorded source or zip without updating and checking the record.
Before publishing, run check after all local source changes. Include the
zip, record and every recorded source in both the package and the explicit
repo push list. Re-fetch those files at the returned commit into a fresh
folder, then run the same check there. A successful push response alone does
not prove that the complete export reached the page.
This contract applies to EDA molecule exports. tscircuit retains
circuit.json and its build inputs; its pipeline generates fabrication
layers. Existing pages are backfilled separately. This source addition does
not enable registry model serving or replace any page's current model.
# Fabrication sources
Every new KiCad, Fusion or Altium molecule export includes `<slug>-fab.zip`
and `export.json`. Make them from the same saved board revision as the STEP.
Finish source edits, including custom-model path rewrites, before exporting.
Use a fresh folder per export so old files cannot enter a new bundle.
The zip contains both sides' copper, solder mask and silkscreen, the actual
board outline, and Excellon drill files. Keep plated and unplated drills
separate where the exporter supports it; record mixed drills honestly.
Keep the original file bytes and names inside the zip. Optional inner
copper, paste and Gerber job files may travel too. Preserve silk PNGs while
the current converter still consumes them.
`export.json` uses the existing `adom.export/1` contract from Fusion PR #17:
- `tool`, `toolVersion`, `exporter`, `exporterVersion`: actual producers.
- `files[]`: relative path, role, byte count and SHA-256 for the STEP, saved
board, schematic sheets and every additional source handed to publishing.
- The `fab_zip` file has `entries[]`, each with its relative path inside
the zip, role, byte count and SHA-256. Nested entries avoid confusing
archive members with real page paths.
- Layer roles: `copper_top`, `copper_bottom`, `mask_top`, `mask_bottom`,
`silk_top`, `silk_bottom`, `outline`; drill roles: `drill_plated`,
`drill_unplated`, `drill_mixed`; optional `paste_top`, `paste_bottom`,
`copper_inner_1` (and subsequent inner layers), `gerber_job` and `other`.
- Source roles: `step`, `board_kicad_pcb`, `board_eagle_brd`,
`board_altium_pcbdoc`, `schematic`, `project`, and descriptive roles for
optional sources (for example `fusion_archive`, `usdz`, `bom`, `cpl`).
- `stackup`: known `thicknessMm`, `copperLayers`, `maskColor` and
`silkColor` by `top`/`bottom`, and `finish`. Unknown values stay null or
absent; never turn a viewer's default into claimed design data.
- `gerbers.included` is true. `drill.plating` says `split` or `mixed`.
Exporters may also preserve `origin`, `outline`, `exportedAt` and their
own provenance. A historical backfill carries `backfill` and its original
`tier`; it must never claim to be a fresh native EDA export.
The helper in this package is Python 3.9+ with no third-party dependencies.
Run it from the package directory, with the export folder as its argument:
```sh
python3 scripts/fab_bundle.py create /path/to/bundle --slug my-board \
--fab /path/to/fresh-gerbers --tool KiCad --tool-version 10.0.3 \
--exporter adom/kicad-export-molecule --exporter-version 1.2.0 \
--source step=Board.step --source board_kicad_pcb=Board.kicad_pcb \
--source schematic=Board.kicad_sch --source project=Board.kicad_pro \
--stackup /path/to/known-stackup.json
python3 scripts/fab_bundle.py check /path/to/bundle --slug my-board
```
Use the versions actually installed, not the example values. `--fab` also
accepts an EDA-produced zip. `--stackup` is optional; pass the data the EDA
provides. Repeat `--source` for every exported source, including every
schematic sheet. The helper writes the canonical zip name without changing
its members' bytes. It refuses missing layers, a blank outline, missing drill
data and changed hashes. It does not prove alignment or validate the circuit;
the existing conversion and manufacturing checks still apply.
For a bridge-produced record, verify it before any packaging rename. If the
bridge used a design stem instead of the wiki slug, use a fresh staging
folder and regenerate the record against the final filenames. Never rename
a recorded source or zip without updating and checking the record.
Before publishing, run `check` after all local source changes. Include the
zip, record and every recorded source in both the package and the explicit
repo push list. Re-fetch those files at the returned commit into a fresh
folder, then run the same check there. A successful push response alone does
not prove that the complete export reached the page.
This contract applies to EDA molecule exports. tscircuit retains
`circuit.json` and its build inputs; its pipeline generates fabrication
layers. Existing pages are backfilled separately. This source addition does
not enable registry model serving or replace any page's current model.