Back to home@LAU-MARS

dsh-cad

deepseek harness 2D and 3D CAD plugin

Stars
2
Language
TypeScript
Created
Aug 20, 2026
Updated
Aug 20, 2026

Introduction

dsh-cad — CAD Plugin for DeepSeek Harness

English | 简体中文

🌐 Homepage: https://lau-mars.github.io/dsh-cad/

A CAD plugin for DeepSeek Harness (dsh): an embedded 3D/2D CAD viewer plus a native parametric modeling tool family (OCCT kernel) in the Web UI, letting the agent build and inspect CAD geometry step by step — "model while you watch".

Preview

An L-bracket modeled live in the chat — profile extrusion, through holes and all-edge fillet as exact OCCT BRep, rendered in the embedded viewer card:

L-bracket modeled with dsh-cad

Feature Overview

CapabilityDescription
🔍 CAD viewingSTL / OBJ / STEP / IGES / BREP (3D), DXF / SVG (2D); interactive in-chat card (orbit / zoom / wireframe / pan)
🏗️ Parametric modelingPrimitives (box/cylinder/sphere/cone/torus), profile extrusion, booleans (fuse/cut/common), all-edge fillet, transforms (translate/rotate/mirror) — exact OCCT BRep, not a mesh approximation
📐 Geometry measurementExact volume (mm³), bounding box, triangle counts, DXF layers
📤 On-demand exportSTEP (parametric) / STL (mesh); files are written only when the user asks
🖥️ Persistent 3D view panelA permanent "3D" tab in the session tab bar: XYZ axes + grid (Z-up) when empty, tracks the latest model in real time while modeling
⚡ Zero-copy render pipelineworker mesh → in-memory binary → three.js typed arrays; zero base64 / zero intermediate files / zero per-step disk writes
💾 Modeling document persistenceOperation log (JSON) + debounced disk mirror; automatically replayed to restore state after a process restart

Modeling Tool Family

ToolDescription
cad_viewOpen a CAD file and render an interactive viewer card
cad_infoRead-only geometry metadata (format / counts / bounding box / units / layers)
cad_create_primPrimitives (mm, Z-up); at for placement, axis for orientation (exact axis-angle rotation)
cad_extrude_profileExtrude a closed XY-plane polygon along +Z into a solid
cad_booleanfuse / cut / common (classic hole punching: plate cut cylinder)
cad_filletConstant-radius fillet on all sharp edges
cad_transformTranslate / Euler rotate / mirror
cad_volumeExact BRep volume (mm³)
cad_exportExport STEP / STL to a workspace path
cad_deleteDelete a body

After every modeling step: the same viewer card refreshes in place (stable viewId + versioned URL), and the "3D" tab tracks the latest model in real time.

Architecture

cad_view(path)                        modeling tools (cad_create_prim, …)
  → import worker (occt-import-js)      → modeling worker (opencascade.js WASM)
  → CadScene JSON (base64-f32)          → exact BRep geometry + meshing
  → GET /dsh-cad/scene/<id>            → in-memory binary scene (f32/u32 packed)
                                        → GET /dsh-cad/bin/<docId>
            ↓ session presentationMeta (viewId + versioned URL) ↓
        browser card + persistent "3D" tab (three.js / SVG, Z-up, XYZ axes)
  • Two workers: import (occt-import-js, read-only STEP/IGES/BREP) and modeling (opencascade.js 1.1.1, full OCCT) are separate, both lazily started; the _N suffix convention of embind overloaded constructors is wrapped in src/modeling/occt-adapter.cjs (all verified at runtime)
  • Zero-copy pipeline: modeling scenes use zero base64 / zero large JSON arrays / zero per-step disk writes (disk mirror debounced 1.5s, replayed only on service restart); cad_export is the only explicit file export
  • Modeling document: <workspace>/.dsh-cad/model.json operation log; all bodies are restored by replay after a restart
  • Client: esbuild single-file CJS factory (three.js inlined ~560KB, react provided by the host module table), Z-up CAD convention, empty scene with XYZ axis labels and a ground grid always displayed

Installation (dev mode)

git clone https://github.com/LAU-MARS/dsh-cad.git
cd dsh-cad
npm install && npm run build && npm test

npm install -g @deepseek-ai/dsh pnpm   # requires Node ≥ 22
dsh web                                  # let the first launch init the profile, then Ctrl-C

dsh plugin --profile web add /path/to/dsh-cad

# append to ~/.dsh/profiles/web/cordis.patch.yml:
#   - insert:
#       - id: dsh-cad
#         name: 'dsh-cad'

dsh web

Set DEEPSEEK_API_KEY and you are ready — for example:

  • “open bracket.stl” → cad_view
  • “model a 100×60×5 plate, punch a ⌀20 hole in the middle, R2 fillets on the four corners, add a ⌀16 boss 20 tall, export plate.step” → cad_create_prim + cad_boolean + cad_fillet + cad_export, with the 3D tab updating live at every step
  • “build a snowman” → spheres + a cone nose + a cylinder hat (precise at/axis placement)

Tests

npm test                             # 26 tests: converters / modeling worker (exact volume assertions) / binary pipeline / document persistence
node test/m0-kernel-check.cjs        # OCCT kernel API smoke test
node test/route-check.mjs            # JSON scene routing layer
node test/visual/serve.mjs           # browser card/tab visual verification page (http://127.0.0.1:3987)

Representative assertions covered: the boolean-punched volume exactly equals the analytic value (28429.20 mm³), L-shaped profile extrusion 3000 mm³, volumes and bounding-box flips of sphere/cone/torus placed with at/axis, 8-byte alignment of the binary packing, and an STL export round-trip (export → read back by the phase-1 parser).

Known Limitations

  • DWG (closed-source) is unsupported; DXF bulge arcs are approximated by chords; glTF/3MF viewing is not implemented (the structure is reserved)
  • cad_fillet is all-edge constant-radius (per-edge selection is unstable under embind); chamfer is not implemented
  • Sketch extrusion supports polygon profiles only (arc profiles are constructed by boolean combinations of cylinders/tori)
  • dsh framework limitation: an already-mounted single slot (the right-side details panel itself) does not respond to components registered later, so the persistent view is provided as the "3D" view tab (a list slot, the official composition)
  • The host reads CAD files via node:fs (the platform fs service supports UTF-8 text only and cannot carry binary data)

Contributors

Auto-generated from the commit history — thanks to everyone who has contributed!

Contributors

License

MIT