Repository navigation
Releases: LAU-MARS/dsh-cad
Release list
v0.15.1 — remove the opencascade.js fallback tier
Highlights
The opencascade.js fallback tier is removed. The kernel chain is now
cadorange → direct occt.ts — and every install gets 64MB lighter
(opencascade.js was the single heaviest dependency).
Why it could go
- It was the chain's only independent wasm binary, but the tier was
capability-crippled: no true B-splines, geometry could not be read back
(shell/draft results became hosted bodies with later edits refused), and
engineering-drawing HLR was unavailable. - Both remaining tiers run the same occt.ts wasm through two independent
code paths (cadorange's public API vs the direct bindings); if neither
boots, the worker now fails with a clean, actionable error instead of
limping on a crippled kernel.
What changed
- dependency dropped;
occt-adapter.cjs(704 lines), the boot fallback
branch and the m0 smoke scripts deleted; - the hosted-body machinery in
occt-bridge.cjs(served only that tier) is
removed with it; DSH_CAD_KERNEL=opencascade.jsnow fails loudly with the removal message
and a migration hint (never silently boots another kernel) — guarded by
the rewrittentest/fallback-kernel.test.ts;- READMEs / docs drop the stale fallback wording.
Verification
Full suite green on both tiers — 190 passed / 3 skipped; explicit boot
checks: DSH_CAD_KERNEL=occt.ts → kernel: 'occt.ts', =opencascade.js
→ clean removal error.
Breaking change
The opencascade.js backend is gone. Unset DSH_CAD_KERNEL=opencascade.js
(or pin cadorange / occt.ts). Install size drops by ~64MB.
Install
dsh plugin --profile web add dsh-cad
# or
npm install dsh-cad@0.15.1v0.15.0 — cadorange as the default modeling backend
Highlights
cadorange is the default modeling backend. dsh-cad's kernel strategy lands:
modeling goes through cadorange (the
agent-native CAD runtime wrapping the same occt.ts/OCCT WASM), with the direct
occt.ts adapter and opencascade.js kept as fallback tiers — and dsh-cad stops
hand-rolling low-level wasm bindings that break on every occt.ts release (this
very release adapts chamfer's new distance2 signature).
What changed
- Default chain: cadorange → occt.ts → opencascade.js. A cadorange boot
failure degrades loudly to the next tier;DSH_CAD_KERNELpins one
explicitly (cadorangehard-fails,occt.ts/opencascade.jspin a tier). - Full 22-verb adapter on cadorange 0.9.0's public API (prims incl.
at/axis, cleaned booleans, fillet/chamfer, extrude/revolve/loft/sweep,
shell/draft, native mirror, describe/volume/centroid, STEP + structured
assembly STEP export), with the supportedcadorange/occtescape hatch for
viewer tessellation, engineering-drawing HLR (same wasm session — no STEP
round-trip, no second instance), 3D sweep spines and periodic B-spline loft
sections. Every verb is mapped indocs/cadorange-integration.md. - occt.ts 0.7.0 → 1.1.0 (cadorange's pinned kernel); the direct adapter
follows the new low-level signatures. STL export stays binary (packed
locally — byte-compatible with the direct backend). - Shape lifecycles: superseded bodies are disposed through the adapter at
every worker drop point (replace/consumed/delete/reset).
Verification
Double parity gate: npm test AND DSH_CAD_KERNEL=cadorange both green on the
full suite — 190 passed / 3 skipped each, exact volume assertions unchanged
— plus a default-chain guard asserting kernel: 'cadorange' on a clean boot.
Breaking change
The default modeling kernel is cadorange. Pin DSH_CAD_KERNEL=occt.ts for the
previous direct backend. occt.ts moves to ^1.1.0; cadorange ^0.9.0 joins as
a runtime dependency.
Install
dsh plugin --profile web add dsh-cad
# or
npm install dsh-cad@0.15.0v0.14.1 — dark-mode surfaces for every viewport, 3D scene and ViewCube
Highlights
Dark-mode surfaces everywhere (fixes #7). The card chrome followed the
host theme, but every rendered surface — viewport slabs, 2D strokes, Three.js
furniture and the ViewCube — stayed light. A new client/theme.ts resolves the
host's signals (color-scheme on <html> and body[data-ds-dark-theme], with
the OS prefers-color-scheme as fallback), exposes a React binding plus one
shared MutationObserver, and drives per-theme palettes.
What changed
- Viewport slabs (chat cards, resident panel, empty Part Studio) use the
themed gradient; a host-defined--dsh-cad-bgstill wins. - 2D entities follow the theme through
--dsh-cad-stroke(dark#c8ced6). - Three.js furniture recolors live on a theme flip: ground grid, XYZ triad
and label sprites, feature edges, default mesh color, sketch fill/wire/points
and the hemisphere ground — mounted viewers keep their camera. - ViewCube plate repaints for dark (dark fill, light labels, dark border)
instead of staying a bright chip on a dark UI. - Drawings keep a white sheet but frame it as paper on the themed slab.
Note: the light-dark() snippet proposed in the issue cannot be used as
written — it accepts only <color>, not linear-gradient() — so theme
resolution is JS-driven and a flip also repaints canvas textures.
Docs & tests
- documented
--dsh-cad-bg/--dsh-cad-stroke/--dsh-cad-paperin both
READMEs; - added
test/theme.test.ts(resolution precedence + dark-palette contrast).
Verification
npm test — 179 passed, 3 skipped (pre-existing environment guards).
Install
dsh plugin --profile web add dsh-cad
# or
npm install dsh-cad@0.14.1v0.14.0 — NURBS/spline loft sections · crease-free skins · live CAD panel
Highlights
NURBS / B-spline loft sections — crease-free skins. cad_loft no longer
reduces every section to a polygon: sections accept {through} splines and
planar {profile} curve chains, and smooth: true fits a periodic B-spline
through plain point loops. OCCT then skins one continuous lateral B-spline
face instead of planar strips meeting at G0 creases (verified: 3 faces — one
B-spline lateral + two caps — versus 6 faces for polygon sections).
Live CAD panel. The resident viewport now follows modeling ops even when
the conversation meta pipeline goes stale: GET /dsh-cad/docs reports each
document's op count as version, the panel polls it (1.5 s, paused while the
page is hidden), advances the scene URL's ?v= (never downgrading), follows
the session's bound document, and auto-returns from a file preview when a new
scene arrives.
What's new
cad_loftsection forms: flat[x,y,z,…]loops (unchanged),{points, smooth},
{through}(closed B-spline through the points),{profile, at, normal, xAxis}
— a 2D curve profile (line/arc/bspline/circle) laid in its own plane.- Top-level
smoothfits a periodic B-spline through plain point loops. GET /dsh-cad/docsdocument entries carryversion(op count); the
?session=<id>active-document block keeps its versioned scene URL.client/doc-revision.ts: shared, visibility-aware liveness poller with a
never-downgrade URL merge.
Fixes
- Single closed B-spline profiles no longer hit
makeWire: wire assembly needs at least 2 parts— a closed spline already
is a wire (regression test added). - Panel: a stale document meta no longer freezes the viewport until a manual
file-list reselect. - Tests: platform-appropriate
resolveSessionPathroots, an inline SVG fixture
(the oldgear_m3_z12_drawing.svgwas never committed), Fusion AddIns install
test skips onEPERM/EACCESinstead of failing sandboxed runs.
Verification
npm test — 170 passed, 3 skipped (skips are pre-existing environment
guards). Fallback kernel (opencascade.js) still boots and models; smooth
sections there are approximated with a closed Catmull-Rom polyline.
Install
dsh plugin --profile web add dsh-cad
# or
npm install dsh-cad@0.14.0v0.13.2 — Panel anchoring on dsh 0.2.1 + issue #6 batch
Highlights
- Panel works on dsh 0.2.1 hosts (issue #6): the side panel anchored itself by DOM sibling order, and 0.2.1's new full-width bottom row broke that guess — the panel mounted but rendered off-viewport. Anchoring now prefers the host's stable
data-rightbar-colmarker and falls back to a full-width-skipping geometric probe, which is correct on old web, desktop 0.2.0 and 0.2.1-alpha alike.
Fixes (issue #6 batch)
- Pattern copies silently overwrote each other: repeating
cad_patternon the same target reused<target>p<i>ids, clobbering earlier copies. Copy ids now uniquify against live bodies (deterministic under replay), and every copy's name is recorded intobodyNames. - Assembly tree false "missing" flags: the flag required a
bodyNamesentry; it now requires BOTH the op-log fold (live body ids) andbodyNamesto lack the body, so pre-fix documents no longer misreport pattern-derived instances. cad_shell/cad_draftsilent no-ops: when the kernel returns the input solid unchanged (chamfered/tangent faces are the known trigger), the tools now throw an actionable error instead of reporting success.- Relative paths resolved against the launch directory:
cad_view/cad_info/cad_image_profile/cad_export(and the external-executor tools) now resolve against the session workspace (agent.session.header.cwd) with the process cwd as fallback, and exports auto-create parent directories. cad_infoon SVG rejected by output validation: scene stats containing non-finite bounds broke lossless-JSON validation; non-finite bounds are now dropped at the boundary.- Feature-tree 404s after drawing/assembly results: assembly and drawing metas now carry
docId(viewId remains the scene id), and the panel's no-sessions fallback filters its latest-result memory by doc kind instead of taking the newest meta of any kind. cad_sketch_listrendered no sketch rows: the value carried the sketches; the renderer dropped them. It now lists one row per sketch.
Deferred from the report
- P2-8 (sweep along a kinked path sweeps only the first segment) and P3-9 (revolve arc direction semantics) touch kernel geometry semantics and get their own release with analytic-volume verification.
Tests
160 tests (was 152): the issue-6 regression suite covers each fix, including the shell no-op repro (chamfered 30 mm cube + shell now throws) and the pattern id collision.
v0.13.1 — Fix worker crash on ESM opencascade.js (issue #5)
Fixes
- "failed to load worker" on ESM opencascade.js resolutions (issue #5): the modeling worker loaded the fallback kernel's emscripten loader with a top-level
require(). Wherever opencascade.js resolves to an ESM-format build, that throws ERR_REQUIRE_ESM at module scope — the worker died before boot(), and the main thread hung waiting for ready until the startup timeout. The loader now runs lazily inside boot()'s fallback branch via dynamicimport()+pathToFileURL, which accepts both module formats; a broken fallback build now surfaces as a clean kernel-init error instead of a silent worker death.
Additions
DSH_CAD_KERNEL=opencascade.js: kernel selector env (bridge level) that forces the fallback backend — useful for diagnostics and for comparing kernel behavior. It backs the new regression test that boots the real worker on the fallback kernel and models a box.
Reminder: occt.ts is the primary modeling kernel since v0.12.x; opencascade.js is the fallback backend only.
v0.13.0 — Desktop client compatibility + cad_script tool
Highlights
- Desktop client (Electron) compatibility: the side panel now clears the frameless window's titlebar drag band (top:
var(--dsh-windows-titlebar-height, 0px), plus-webkit-app-region: no-draginsurance). Chromium computes drag regions geometrically, so the full-width drag strip swallowed every click on the Part Studio / + tab strip. Web hosts are unaffected — the variable is only set by the desktop shell and falls back to 0. - New
cad_scripttool: deterministic script evaluation for geometry math (profile point arrays, arc coordinates, transform math).language: "js"runs in-process in a Node vm — no child process, so it works even where the host shell is sandboxed (the desktop runtime's pwsh currently fails every spawn with 0xC0000142);language: "py"uses a system Python when the host permits spawning.
Fixes
- Duplicate route explosion on desktop (
webserver: duplicate prefix route "/dsh-cad/scene"): the plugin discarded the webServer route disposers, so when the desktop runtime hot-reloaded the plugin in-process, the next apply() re-registered 7 routes on the shared server and every viewer-dependent tool call failed until a full process restart. Disposers are now collected and run on unload, with rollback of partial batches. Web hosts never reload plugins — which is why only the desktop client hit this. - Panel resilience to host UI drift:
GET /dsh-cad/docs?session=<id>reports the session's bound active document with a versioned scene URL, giving the resident panel its own channel when the conversation-meta pipeline is unavailable (host version drift, cold start).
Changes
- Single display area: in-chat CAD tool cards are now one-line summary rows (title + stats + pointer to the panel); the resident right panel is the only CAD viewport. The rows still feed the panel's latest-model fallback memory.
Tests
151 tests (was 143): new route-registration lifecycle regression suite and the cad_script suite.
v0.12.2 — Fix git-URL installs: ship the lib/ build output in-repo
Fixes
- "failed to import" on activation after a git-URL install: installing from the repository URL fetches the repo as-is, and the
lib/build output was gitignored — so the installed package had nomainentry to import. Apreparehook is not the answer: pnpm 10+/11 blocks dependency build scripts by default (allowBuilds) and the install would hard-fail. The build output is now committed in-tree, sopnpm add https://github.com/LAU-MARS/dsh-cadworks out of the box with zero build scripts (verified end-to-end: fresh git-URL install, entry imports cleanly, plugin surface apply/inject/name intact). The npm tarball is unchanged.
Also in the 0.12.x line:
- 0.12.1:
@deepseek-ai/dsh-toolspeer range widened to>=0.0.1-rc.1— dsh-tools is versioned in lockstep with the dsh runtime, so 0.1.7-rc.x runtimes no longer reject the plugin; verified against SDK 0.1.7-rc.2 (build + 143 tests pass). - 0.12.0:
cordis.patch.ymlnow ships in the tarball (dsh install no longer rejected), occt.ts kernel resolves through Node's own resolver (npm/yarn flat + pnpm layouts), named sketches + feature tree panel.
v0.12.1 — Fix dsh-tools peer range for modern dsh runtimes
Fixes
- dsh 0.1.7-rc.x rejected the plugin as incompatible: dsh-tools is versioned in lockstep with the dsh runtime, so dsh 0.1.7-rc.1 provides @deepseek-ai/dsh-tools 0.1.7-rc.1 — outside the old ^0.0.1-rc.1 peer range, and the runtime refused the install ("may cause crashes or data loss"). The peer range is now >=0.0.1-rc.1, covering every dsh-tools from the original 0.0.1 line through current 0.1.7 runtimes.
- Verified against the modern SDK: devDependency bumped to @deepseek-ai/dsh-tools 0.1.7-rc.2 — full build and all 143 tests pass against it.
If you previously hit the ENOENT cordis.patch.yml or the occt.ts-kernel-not-found issues, v0.12.0 already fixes those (#1, #2, #4).
v0.12.0 — Named sketches + feature tree panel
Highlights
- Named sketches:
cad_sketch_new/cad_sketch_list/cad_sketch_edit/cad_sketch_delete— sketches live in the document op log;cad_sketch_editrewrites the defining op in place and the full replay rebuilds every referencing feature (the parametric loop). Profile-drivencad_extrude_profile/cad_revolve/cad_sweepreference sketches by name. - Feature tree panel: the Part tab gains an Onshape-style structure card — one chronological row per sketch (✏️ blue, toggles the viewport's sketch curves + plane frame) and per feature (highlights + shows/hides its body). Data comes from the new
GET /dsh-cad/tree/<docId>route, folded from the document op log (works after restarts, no worker round-trip).
Fixes
- dsh install rejected (ENOENT cordis.patch.yml): the overlay file was excluded by the package.json
fileswhitelist and missing from the published tarball — it now ships (fixes #1, fixes #4). - occt.ts kernel not found on normal installs:
resolveDistDir()only searched the package's ownnode_modules; it now resolves theocct.tsdependency through Node's own resolver, walking every parentnode_modules— npm/yarn flat and pnpm symlink layouts all hit (fixes #2).