The Verify Loop
You write a .brep.ts part; the brepjs-verify CLI runs it against a real geometry kernel and tells you the truth. Never judge a part by how the code reads — judge it by the report. This loop is the whole job, whether you are the agent or the human driving it.
The loop (every part, in order)
- Brief. Convert the request into explicit parameters: dimensions (mm), datums, features, assumptions.
- Author
.brep.ts.export default () => <shape>using the short API (box,cylinder,fuse,cut,fillet, …), with named constants at the top. Scaffold withbrepjs-verify init <name>. Edit source, never generated artifacts. - Declare intent. Add an
expectedblock from your brief, e.g.export const expected = { volume: 24000, tolerancePct: 1 }. Any ofvolume,area,boundsare optional;tolerancePctsets the match window. The CLI asserts it — this is how you prove the part is the right part, not just a valid one. - Verify (type + geometry).
brepjs-verify verify part.brep.ts --check --json report.json.--checktype-checks before running (catches wrong-API calls early); the JSON report is the source of truth. Iterate fast withbrepjs-verify watch part.brep.ts. - Verify visually. Add
--snapshot shots/for iso/front/top/right PNGs. Review against the brief. A visual concern is not a conclusion — convert it to a measurement ("hole looks off-center → checkbounds"). - Repair the smallest responsible section and re-run. Use the report's
hintsto guide the fix. - Export + hand off.
brepjs-verify verify part.brep.ts --step part.step(STEP is the validated primary deliverable; GLB/STL are derived). Batch behind a validity gate withbrepjs-verify export part.brep.ts --all. Report the STEP path.
The commands above assume you've installed the package (npm i -D brepjs-verify) and call brepjs-verify directly. Otherwise prefix every command with npx -y to run it straight from npm.
Reading the report (this is the source of truth)
Every command writes a single JSON document to stdout (diagnostics go to stderr):
{
"ok": false, // true only if no errors AND every check AND every assertion passes
"shapeType": "Solid",
"checks": [{ "name": "isValidSolid", "passed": false }],
"measurements": {
"volume": 31200,
"area": 6800,
"bounds": { "xMin": -20, "xMax": 20, "yMin": -10, "yMax": 10, "zMin": 0, "zMax": 10 },
},
"assertions": [{ "name": "volume", "expected": 24000, "actual": 31200, "passed": false }],
"hints": [{ "code": "FILLET_NO_EDGES", "message": "…", "fix": "…", "nextStep": "…" }],
"errorInfos": [{ "code": "…", "message": "…" }],
}okis the verdict.false→ not done. With anexpectedblock,okalso requires every assertion to pass.checks= kernel validity (manifold solid, positive volume). A failed check means the geometry is broken, not just wrong-sized.measurements= the kernel's measured volume / area / bounding box.assertions= your declared intent vs reality. A failed assertion means valid-but-wrong (off dimensions).hints= an actionable fix + next step keyed on the error code. Read these before guessing.errorInfos= the raw structured failures (code+message) the hints derive from — authoring, kernel, or export errors. Cite thecodewhen repairing.
Trust this JSON over the rendered image. The render confirms shape; the JSON confirms correctness.
Repair discipline
- Change the smallest responsible section, re-verify, repeat. Don't rewrite the whole part on one failure.
- Let the
code/hintslocalize the cause:INVALID_FILLET_RADIUS→ reduce the radius relative to the local edge length.*_NOT_3D→ you passed a 2D shape to a 3D operation.BOOLEAN_HAS_ERRORS→ the inputs are overlap-degenerate.
- A part that runs but reports
ok: falseis wrong, not done — same as a crash.
What's reliable, what needs care
- Reliable first-try: primitives, booleans (
fuse/cut/intersect), 2D sketch → extrude,fillet/chamfer,shell/offset, transforms. Prefer these. - Advanced — verify extra carefully, expect iteration: sweeps, lofts, revolves, multi-section, assemblies, text. They fail more often (degenerate profiles, self-intersection); lean harder on the report and take small steps.
Hard rules
- Edit source, not artifacts. STEP/STL/GLB derive from the
.brep.ts. - Booleans and
measureVolume/measureAreareturnResult— unwrap and check theErrbranch before chaining. fillet/chamferneed a valid solid; the signature isfillet(solid, edges, radius). Verify validity first.box(width, depth, height): the 2nd arg is depth (Y), the 3rd is height (Z); the positioning option isat, notorigin. Units are mm.- Author parts in an ESM context so the kernel loads — a CommonJS project needs
"type": "module"or a.mtsfile.
Programmatic use
The same runtime is exported for scripts and your own harnesses:
import { runPart, serializeReport } from 'brepjs-verify';
const { shape, report, step } = await runPart('part.brep.ts', { step: true, check: true });
console.log(serializeReport(report)); // { ok, shapeType, checks, measurements, assertions, hints, errorInfos, errors }report.shape is a live WASM-backed handle — release it (using / a DisposalScope) in long-running callers.
Next steps
- CLI Reference — every subcommand and flag
- Examples — the few-shot gallery
- Troubleshooting — ESM, snapshots, kernel