Bundle
dsh-cad
CAD visualization plugin for DeepSeek Harness: cad_view / cad_info tools with an embedded 3D (STL/OBJ/STEP/IGES) and 2D (DXF/SVG) viewer card in the Web UI
- Source
- LAU-MARS
- stars
- 7 stars
- License
- MIT
- Updated
- Updated 7 days ago
Readme
# dsh-cad — CAD Plugin for DeepSeek Harness

[](https://lau-mars.github.io/dsh-cad/)
[](https://www.npmjs.com/package/dsh-cad)
[](https://github.com/deepseek-ai/deepseek-harness)
[](https://nodejs.org/)
[](https://github.com/donalffons/opencascade.js)
[](./LICENSE)
English | [简体中文](./README.zh-CN.md)
A CAD plugin for [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness):
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
The CAD editor at startup: the demo L-bracket parsed from the packaged
`demo-bracket.brep` by OCCT — face + edge rendering, hover measurement of the
picked face (4,800 mm²), a ViewCube navigation cube in the corner, and
switchable demo parts (bracket / flange / shaft):

## Feature Overview
| Capability | Description |
| --- | --- |
| 🔍 CAD viewing | STL / OBJ / STEP / IGES / BREP / DCPRT (3D), DXF / SVG (2D); interactive in-chat card (orbit / zoom / wireframe / pan) |
| 🧭 CAD editor interactions | Onshape-style ViewCube (26-zone click-to-orient), hover/click face & edge picking with live measurement (area mm² / length mm), Faces+Edges / Faces / Wireframe render modes, switchable BRep demo parts (bracket / flange / shaft) |
| 🏗️ Parametric modeling | Primitives (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 |
| 🗂️ Codex-style document tabs | The resident display panel gets a tab strip with a "+" menu: **Part** (Part Studio, the default) / **Assembly** (instance insert/move/remove) / **Drawing** (true hidden-line sheets); tabs are closable and keep their state |
| 📐 Engineering drawings | GB first-angle layout: front / top / left views + isometric, true OCCT hidden-line removal via the **occt.ts** kernel (an npm dependency, dashed); sheet frame, title block, overall dimensions, standard scale series; exports SVG / DXF |
| 📐 Geometry measurement | Exact volume (mm³), bounding box, triangle counts, DXF layers |
| 📤 On-demand export | STEP (parametric) / STL (mesh); files are written only when the user asks |
| 🖥️ Resident CAD panel | A permanent panel right of the conversation: Codex-style tabs (Part / Assembly / Drawing), tracking the latest model in real time while modeling |
| ⚡ Zero-copy render pipeline | worker mesh → in-memory binary → three.js typed arrays; zero base64 / zero intermediate files / zero per-step disk writes |
| 💾 Modeling document persistence | Operation log (JSON) + debounced disk mirror; automatically replayed to restore state after a process restart |
| 🖼️ Image → profile | PNG sketch/screenshot → Otsu binarization → contour tracing → extrusion-ready polygon (`cad_image_profile`) |
| 🔌 FreeCAD executor | Run the same op family on an external FreeCAD console (STEP in/out); requires a local FreeCAD install |
## Installation
The plugin is published to npm — one line:
```sh
dsh plugin --profile web add dsh-cad
```
The installer applies the bundled `cordis.patch.yml` (declared in the `dsh.bundle` manifest) automatically, so there is nothing to configure by hand.
### Version requirements
- **Node.js** ≥ 22
- **dsh CLI** (`@deepseek-ai/dsh`): this plugin is developed against **0.1.0-rc.7**
(minimum supported version, declared in the `engines` field of `package.json`);
recommended **≥ 0.1.1-rc.2** (verified 2026-08-31)
### Install from source (dev mode)
```sh
git clone https://github.com/LAU-MARS/dsh-cad.git
cd dsh-cad
npm install && npm run build && npm test # deps include occt.ts (true-HLR drawing kernel, ~20MB wasm)
npm install -g @deepseek-ai/dsh@^0.1.1-rc.2 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
dsh web
```
The patch insert ships as `cordis.patch.yml` in the package root and is applied by the installer via the same `dsh.bundle` manifest.
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)
- “add two more b1, one rotated 90 degrees” → `cad_assembly_insert` + `cad_assembly_move`, the Assembly tab updates live
- “make an A3 drawing of b1 and export dxf” → `cad_drawing` (three views + iso + dashed hidden lines + dimensions) → `cad_export` `.dxf`
## Modeling Tool Family
| Tool | Description |
| --- | --- |
| `cad_view` | Open a CAD file and render an interactive viewer card |
| `cad_info` | Read-only geometry metadata (format / counts / bounding box / units / layers) |
| `cad_create_prim` | Primitives (mm, Z-up); `at` for placement, `axis` for orientation (exact axis-angle rotation) |
| `cad_extrude_profile` | Extrude a closed XY-plane polygon along +Z into a solid |
| `cad_boolean` | fuse / cut / common (classic hole punching: plate cut cylinder) |
| `cad_fillet` | Constant-radius fillet on all sharp edges |
| `cad_transform` | Translate / Euler rotate / mirror |
| `cad_volume` | Exact BRep volume (mm³) |
| `cad_drawing` | Engineering drawing: front/top/left + isometric views, dashed hidden lines, frame, title block, overall dimensions, standard scale, A4/A3 |
| `cad_assembly_insert` | Insert a body into the assembly as a placed instance (`at` position, `rotate` orientation) |
| `cad_assembly_move` | Set an instance's absolute placement |
| `cad_assembly_remove` | Remove an instance from the assembly (the body stays) |
| `cad_export` | Export STEP / STL / DCPRT (the native replayable part document) to a workspace path; `target: "assembly"` writes the assembly STEP, `target: "drawing"` writes the sheet as SVG / DXF |
| `cad_delete` | Delete a body |
| `cad_freecad` | Run an op program on an external FreeCAD executor (optional STEP input / export) |
| `cad_fusion` | Run an op program on an external Fusion 360 executor (GUI bridge; optional export) |
| `cad_image_profile` | PNG → contours → extrusion-ready polygon points |
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.
## Connectors (roadmap)
Modeling today runs on the **built-in WebGL-class kernel** (OCCT in the browser —
zero install). The connectors below refer to **external CAD engines** acting as
executors for the same tool family, planned for future support:
| Connector | Suite | Platform | Status |
| --- | --- | --- | --- |
| **Built-in kernel** | CAD modeling kernel based on OCCT + WebGL, runs in the browser — zero install | All platforms (WebGL rendering) | ✅ Built-in |
| FreeCAD | open-source parametric suite — natural local executor via its Python API (console + GUI window modes) | Windows / macOS / Linux | ✅ Available (needs local install) |
| Fusion 360 | Autodesk CAD/CAM — resident add-in + spool bridge (no headless; the Fusion window doubles as a viewer) | Windows / macOS | 🧪 Experimental (`cad_fusion`) |
| SolidWorks | Dassault Systèmes industry-standard 3D CAD, COM/.NET automation | Windows only | 🚧 Windows demo scaffold (`scripts/solidworks-bridge/`) |
| Onshape | cloud-native SaaS CAD, fully in the browser | All platforms (browser) | 🚧 Planned |
| ZW3D(中望3D) | ZWSOFT all-in-one CAD/CAM | Windows / Linux | 🚧 Planned |
| GstarCAD 3D(浩辰3D) | Gstarsoft 3D CAD | Windows | 🚧 Planned |
All external engines implement the same **GeometryExecutor contract** (`available()` /
`run(opProgram) → meshes`), so the WebGL display layer never changes — swapping a
backend changes only the quality of the produced geometry.
## 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
- **Drawing HLR kernel**: hidden lines run on **occt.ts** (npm dependency,
`npm i occt.ts`) — true OCCT removal, no fallback engine, a missing kernel is
a hard error. New APIs over opencascade.js: `hiddenLines()` true hidden-line
removal, byte-level STEP/BRep `readStep`/`readBrep`/`writeStep`/`writeBrep`
without MEMFS, tessellation with built-in feature-edge extraction, and a
`hasError()`/`lastError()` error contract. Geometry crosses kernels as STEP
bytes and the projected segments are remapped into the sheet frame. Kernel
dist resolution: `DSH_OCCTJS_DIST` env var → `node_modules/occt.ts/dist`
(npm, default) → `<repo>/../opencascade-ts/dist` (sibling checkout) → `vendor/`
→ `node_modules/opencascade-ts`
- **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
## Tests
```sh
npm test # 41 tests: converters / modeling worker (exact volume assertions) / DCPRT round-trip / FreeCAD executor / image profiles / binary pipeline
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, an STL export round-trip (export → read back by the
phase-1 parser), and a DCPRT document round-trip (serialize → replay on the
OCCT worker → exact bounds).
## 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!
[](https://github.com/LAU-MARS/dsh-cad/graphs/contributors)
## License
MIT
Install
dsh plugin --profile web add github:LAU-MARS/dsh-cad#a9314e76808c0ba8b93015cf10fae1755e83c54b
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-cad from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.