DWG and DXF to JT
on the machine the drawing lives on
One Windows executable that turns architect and supplier drawings into JT 8.1 assemblies for JT2Go and Siemens Process Simulate. No Python, no CAD licence, no upload, no account. The drawing never leaves the workstation.

The shipping desktop build. One page, one button.
The Problem
Process Simulate accepts JT and nothing else. The drawings arrive as DWG and DXF.
Commercial converters
about $15,000 per seat, per year
Hard to justify for a handful of conversions a month.
Re-export from the original CAD system
needs the licence for that system
The person holding the licence is rarely the person who needs the JT.
Cloud converters
the drawing has to be uploaded
For plant layouts and supplier geometry, that is often a straight no.
Open-source tooling
LibreDWG and ezdxf, by hand
A toolchain, not a tool. It assumes Python, a shell, and someone to maintain both.
CadPal is the fourth option: one file the engineer double-clicks.
How A Conversion Runs
Four local stages, and the last one is a proof.
The writer checks itself
An independent parse-back verifier reads the file the writer just produced and asserts the segment table, LOD structure and geometry counts, instead of trusting the writer's own bookkeeping.
Damaged drawings still convert
When a DWG's block-header ownership chain is broken, a fallback path rebuilds it from a dwgread JSON dump rather than failing the job.
Every run is itemised
The conversion report lists what converted and what was skipped, with a reason per skip. Curved ACIS solids surface as unsupported_curved_solid, never silently dropped.
On Device
The whole engine is inside the executable.
Loopback only
In the packaged app the engine binds 127.0.0.1 on a port chosen at boot. Nothing is reachable from the network and nothing calls out.
Tools travel with the app
LibreDWG, every DLL it imports, and a 32-bit Python 3.8.10 with ezdxf are carried inside the executable. There is nothing for the user to install.
The cloud path was removed
Native converter tooling cannot run on Deno, so the Supabase edge function was abandoned and returns HTTP 501 by design. There is nothing left to switch on by accident.
The Windows 7 Target
Every silent failure on the target now has a gate that refuses to ship it again.
The target machine is a Windows 7 SP1 workstation with PowerShell 2.0, no build tools, and no administrator patience. Five faults landed in four days of field testing, each one passing on every developer and CI machine and dying without a message on the target.
The window never opened
electron-builder 25 rebuilt node_modules from an npm ls tree and put archiver-utils where the top-level zip-stream could not resolve it.
scripts/verify-packaged-deps.js
Applies Node resolution across the packaged tree. dist:win packs, verifies, then packages.
A blank white window, no error
Vite's default base of '/' emits absolute asset paths, which resolve to the drive root under loadFile's file:// origin and load nothing.
client/vite.config.js
base: './' plus target: 'chrome108' for Electron 22. Renderer errors now reach the log.
The interface never found the engine
Electron 20 and later sandbox preloads, so require of a relative file failed and the renderer was never told which port to call.
electron/main.js
sandbox: false with context isolation kept. Preload errors are logged, not swallowed.
Convert did nothing, exit 0xC0000135
The LibreDWG win32 zip omits libwinpthread-1.dll, which libgcc imports. Every developer and CI box hides the gap by having MinGW on PATH.
scripts/verify-bundled-dlls.js
Reads PE import tables and the Windows 7 subsystem ceiling. Failures now name STATUS_DLL_NOT_FOUND.
No converting build could be produced at all
Frozen Python sidecars needed a Windows box or CI, and the organisation account was billing-locked, so Actions could not run.
scripts/stage-python-win32.js
Stages a sha256-pinned 32-bit Python 3.8.10 and ezdxf from macOS, straight into the build.
The pattern that worked every round: read the artifact the failure left behind, reproduce it locally, fix it, then add a check that fails the build rather than the customer.
What It Does Today
Shipping, and what is not.
Phase 0, current
On-device DWG and DXF to JT with zero OpenCASCADE. Shipping and in acceptance testing on the target hardware.
Phase 1
STEP and IGES, two-way, through the OpenCASCADE bridge.
Phase 2
CATPart and SAT. Parked, and likely to need a commercial SDK.
Output is JT 8.1 tessellated geometry for visualisation and simulation, not solid modelling. CadPal converts, verifies and reports. It is not a CAD editor.