Repository navigation
release: promote v0.20.0 to main - #429
Merged
Merged
Conversation
…ity (DD-031 G1-G6, E1/E4) Phase 2 of the consumer-UX pass: no shipped capability stays reachable only via raw.renderer(), and every new public controls method is exposed + parity-tested across Vue/React/Svelte/Web Component. Core (gcode-preview-core): - GcodePreviewControls gains getRenderStats() (G1), pickSegment() (G2), and isColorModeAvailable() — the render-diagnostics and source-mapping surfaces were previously ToolpathRenderer-only. - GcodePreviewState gains availableColorModes/hasRetractions/hasColorChanges (G6), refreshed post-parse from the renderer's honest capability gates, so a UI can offer+explain controls without the raw handle. - PreviewRenderer widened accordingly; the 2D adapter implements the new members honestly (getRenderStats null; no fabricated stats). Adapters: - Declarative hiddenFeatureRoles (G3) on all four (prop / prop / prop / hidden-feature-roles attribute), diffing prev->next so it only toggles roles it owns. Backs the AnyBridge hide-adhesion feature declaratively. - capture() promoted to the Vue/React/Svelte handles (G5), matching the WC method. - Web Component: renderer/adjacentLayers property accessors (E1); index re-exports RendererMode/PreviewRenderer (E4). Tests: portable behavioral suite extended (layer-range clip, color-mode gating, diagnostics+picking reachability) plus a controls-completeness parity guard so a capability can't ship in core and vanish from an adapter. The guard caught React's hand-listed harness controls; fixed to delegate the whole controls object. Docs: DD-031 (accepted) records the audit, parity matrix, gaps, and Feature-Lab architecture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bility gaps (DD-031) - adapters.md: replace the overstated "12-prop identical surface" with the real ~24-prop shared surface grouped by intent; correct the WC attribute-vs-property split; add the imperative surface (getRenderStats/pickSegment/isColorModeAvailable/capture) and capability-aware state; note the deliberate per-framework differences. - Four adapter READMEs aligned to the verified surface: React README no longer omits onParseCancelled/onParseProgress; showRetractions/cameraMode/theme documented across all (not WC-only); core README names all four adapters incl. the Web Component; new hiddenFeatureRoles + reachable diagnostics/picking/capture added; WC property-only options, DOM event-detail wrapping, and Svelte's .svelte subpath documented as intentional. - CLAUDE.md: add the mandatory framework-parity completion check (mission process rule). - Changeset: additive minor across core + four adapters (lockstep). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-free toolpath cutouts
AnyBridge thumbnail parity: capture({ background:'transparent' }) on the toolpath
renderer baked in the build-plate grid, because the grid/bed/origin/cage are scene
geometry the transparent backdrop swap doesn't touch — so a consumer couldn't produce
a clean toolpath-only cutout the way ModelRenderer does.
Adds CaptureOptions.includeBuildVolume (default true = current behavior). When false,
ToolpathRenderer.capture hides its build-volume group for the off-screen render only and
restores it synchronously in a finally (no intermediate frame painted → live view
untouched). Flows through GcodePreviewControls.capture to all four adapters; a no-op
where there is no build volume (ModelViewer) or no capture (2D renderer).
Test: a capture-capable stub GL records the group's visibility at render-to-target time —
false with includeBuildVolume:false, true by default, restored to visible afterward.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… controller (DD-031 P3/P4) Replaces the inherited sidebar-of-fieldsets engineering harness with a viewport-dominant "Feature Lab" built on @chestnutlabs/gcode-preview-core (the published controller) — it now dogfoods the real adapter surface instead of importing the raw ToolpathRenderer. - New workspace-internal (unpublished) tools/demo-kit: a design-token CSS system, capability- aware control metadata + default color-mode palettes, an organized fixture catalog (by purpose, not filename), and formatting helpers — shared substrate for the demo and the framework showcase examples. - Layout: compact header (brand + file/job + capture + chrome light/dark), viewport as the hero with floating legend + quick camera controls + count pill + stage banner, an intent- grouped inspector rail (Inspect / Appearance / View / Render / Machine / Progress / CNC / Diagnostics), a bottom Layers/Segments/Time scrub strip, and an honesty status bar. - Contextual + capability-aware: color modes gray out with a plain-language reason when the file lacks the channel; the Hide brim/skirt toggle appears only when feature roles are known; the CNC tab appears only for tool-power files; capability badges are tiered known/inferred/unavailable. Diagnostics reads getRenderStats() through the public controls, and clicking the model reads pickSegment() — the previously-dark surfaces, now first-class. - Preserves keyboard camera/scrub shortcuts and focus styles. Verified in a headless Chromium: skirt-brim parses (454 seg / 14 layers / 3m04s), feature coloring + legend, hide-adhesion removes skirt/brim live, getRenderStats returns the SwiftShader diagnostics, contextual gating correct. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…1 P4) Restructure the React example into the DD-031 §4.7 two tiers, both driving the real @chestnutlabs/gcode-preview-react (no raw renderer/session): - minimal.html / minimal.jsx — smallest real integration: <GcodePreview source> plus a fixture picker and a layer slider. One short file to copy. - showcase.html / showcase.jsx — full declarative surface mirroring the Feature Lab's capability-aware UX in React idiom: color modes gate on the file's capabilities with a plain-language reason, feature-role hiding is a declarative prop, diagnostics + picking come through the ref handle's controls. Styled with the shared workspace-internal demo-kit (tokens + capability metadata + fixtures). - index.html — landing linking the two tiers. - vite.config: multi-page input, publicDir=test-data (demo-kit fixture paths), server.fs.allow for the ../demo-kit relative import. Verified headless: minimal loads 3DBenchy (240 layers); showcase parses skirt-brim (454 seg / 14 layers), badges tier known/unavailable correctly, color modes gate with reasons, getRenderStats reports 3d-webgl/tubes/GPU, hide-adhesion applies — zero console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(DD-031 P4) Greenfield Vue example (there was none), mirroring the React reference and driving the real @chestnutlabs/gcode-preview-vue: - Minimal.vue — smallest real integration: <GcodePreview :source> + fixture picker + layer slider, ordinary reactive state driving declarative bindings. - Showcase.vue — full declarative surface in Vue idiom: capability-gated color modes with reasons, declarative :hidden-feature-roles, diagnostics/picking via the component ref's handle (viewer.preview.controls). Shared demo-kit styling. - index landing, multi-page vite (plugin-vue), publicDir=test-data, fs.allow demo-kit. - launch.json: example-vue (5203) + example-webcomponent (5204) placeholders. Verified headless: minimal loads calicat (174 layers); showcase parses skirt-brim (454 seg / 14 layers / 3m 04s), badges tier correctly, 3 modes gate with reasons, getRenderStats reports 3d-webgl/tubes/GPU — zero console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…31 P4)
Restructure the Svelte example into the DD-031 §4.7 two tiers, both driving the
real @chestnutlabs/gcode-preview-svelte via the deliberate .svelte subpath:
- Minimal.svelte — smallest real integration: <GcodePreview {source}> + fixture
picker + layer slider, ordinary reactive state driving declarative props.
- Showcase.svelte — full declarative surface in Svelte idiom: capability-gated
color modes with reasons, declarative hiddenFeatureRoles, diagnostics/picking via
the bound handle (viewer.preview.controls); the handle's store-contract `state`
read for the ready-omitted fields. Shared demo-kit styling.
- index landing, multi-page vite (plugin-svelte), publicDir=test-data, fs.allow.
- Replaces the single App.svelte/main.js.
Verified headless: minimal loads 3DBenchy (240 layers) and vase (1, spiral);
showcase parses skirt-brim (454 seg / 14 layers / 3m 04s), badges tier correctly,
3 modes gate with reasons, getRenderStats reports 3d-webgl/tubes/GPU — zero errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…1 P4)
Greenfield vanilla-JS example (there was none), driving the published
<gcode-preview> element from @chestnutlabs/gcode-preview-element:
- minimal.js — smallest real integration: import /define to register, set the
`source` property, listen for `ready`; the layer slider drives the `layer-range`
attribute. Teaches the attribute/property split in ~40 lines.
- showcase.js — full surface in vanilla JS mirroring the Feature Lab: objects
(source, colorMode, hiddenFeatureRoles) set as properties; primitives
(layer-range, view) as attributes; capability-gated color modes with reasons;
diagnostics/picking via element.controls; disclosure read from the WC's wrapped
{ text } detail. Shared demo-kit styling.
- index landing, multi-page vite, publicDir=test-data, fs.allow demo-kit.
Verified headless: minimal loads 3DBenchy (240 layers, layer-range attr path) and
mach3; showcase parses skirt-brim (454 seg / 14 layers / 3m 04s), badges tier,
3 modes gate, getRenderStats reports 3d-webgl/tubes/GPU, hiddenFeatureRoles=[6,7],
colorMode/layer-range/showTravel mutations all apply — zero console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…31 P4) - React/Svelte README "Example" → "Examples": describe the minimal + showcase tiers and the correct --prefix run command (tools/* are not workspaces). - Vue/Element READMEs: add the missing "Examples" section (both now have real example apps — a greenfield Vue app and the first Web Component example). - adapters.md: add a "Try the examples" table (adapter → dir → port) and the minimal/showcase split. docs:links OK (245 internal links). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rity (DD-031 P4) - Each showcase publishes its handle as window.gcodePreview after `ready` (devtools/ inspection convenience, mirroring the Feature Lab's window.viewer; also what the documentation screenshot harness composites through). - Web Component: on build-complete, a null getRenderStats() read now renders nothing instead of "(no stats — renderer not ready)", matching the three framework showcases (stats populate a tick after build-complete; the button reads on demand). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rfaces Add a 2026-08-29 (DD-031) coverage-delta section: the Feature Lab rebuild and the four two-tier adapter examples are new *demonstration surfaces* (no new engine capability), and getRenderStats/pickSegment are now reachable through the public adapter surface. Update section 10's adapter row + a capability-aware-UX row. Honest media status: dark app-UI review screenshots were captured but are NOT yet canonical docs/media assets — the manifest harness produces the mid-grey capability presentation, not app chrome. Deferred (recorded) to the next Visual Review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…minimals (DD-031 live-pass)
Fixes from the owner's live UX pass:
- Feature Lab: the rail-collapse (☰) button was pinned to the viewport's top-right
corner, overlapping the camera cluster's projection (perspective/orthographic)
toggle. Moved it to a vertically-centered handle on the rail seam, clear of the
camera controls.
- Web Component showcase: "Show travel moves" read as off (checkbox unchecked) but
travel still rendered — the element keeps its own defaults (showTravel=true) and
the showcase never pushed the initial state. Now applies the initial toggle state
on startup, so the control matches what's drawn. (The framework showcases bind
showTravel declaratively and already applied it on mount.)
- Minimals (all four): default travel moves off (showTravel={false}) for a clean
first-render, matching the showcases.
Verified headless: Feature Lab camera cluster unobstructed; WC showcase travel off
by default and toggles on correctly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…apter (DD-031) Make interactive source-model viewing (STL/3MF) a first-class, declarative half of the SDK — the Prepare side alongside the toolpath Preview side (owner decision). gcode-model-renderer (new, framework-neutral): - createModelPreviewController — the Prepare-side analogue of gcode-preview-core's toolpath controller: lazy engine on bindCanvas (the engine takes its canvas at construction; the controller defers + rebuilds on canvas replace, replaying the last source), an op queue, and a reactive state snapshot (getState/onStateChange) derived from the engine's events. Wraps the existing createModelViewer unchanged (no renderer redesign). ModelPreviewControls/State contract exported. - /testing subpath: runModelBehavioralSuite + controls/state completeness parity guards + shared stub GL/controls + STL/coloured source makers. gcode-preview-react/model (new subpath): - useModelViewer hook (useSyncExternalStore over the controller) + <ModelViewer> component shell. Thin bridges — never a separate viewer. Tests: model-renderer 69 (controller: lazy bind, pre-bind queue, capability passthrough, rebind-replay, unsupported-renderer); react 20 (model behavioral suite: both parity guards pass through the adapter). No regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rs (DD-031) Complete the model-viewer adapter family — source-model (Prepare) viewing now has first-class declarative parity across all four frameworks, each a thin shell over the shared createModelPreviewController (never a separate viewer): - gcode-preview-vue/model — useModelViewer composable + <ModelViewer> component. - gcode-preview-svelte/model — createModelViewer store/action + ModelViewer.svelte (raw component via the /model/ModelViewer.svelte subpath + copy-svelte step). - gcode-preview-element/model — <gcode-model-viewer> element + defineGcodeModelViewer (+ /model/define auto-register subpath); tag avoids the reserved <model-viewer>. Each adds the gcode-model-renderer dep + a /model subpath export, and runs the portable runModelBehavioralSuite with both parity guards (controls + state completeness) through its own public surface. Tests green, no regressions: vue 39 (33+6), svelte 22 (16+6), element 23 (17+6), react 20 (14+6), model-renderer 69. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…showcase (DD-031) - demo-kit/models.js: synthetic MIT-clean source-model fixtures (STL tower → materials unavailable; colored 3MF → materials known), each source() returning a ready ModelSourceInput. Plus model-3mf-fixture.js (the generated base64 3MF). - example-react showcase: a Preview/Prepare mode toggle demonstrates both halves of the SDK in one app — <GcodePreview> (sliced G-code) and <ModelViewer> (source model, via /model), with the model side surfacing the materials capability tier + object/ placement counts. - example-react: new model.html minimal — the smallest <ModelViewer source> integration, linked from the landing as a third tier. Verified headless: Prepare loads the colored 3MF (3 objects, materials KNOWN), toggles back to Preview cleanly; minimal model loads the STL (1 object, materials unavailable). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ll showcases (DD-031) Demonstrate both halves of the SDK everywhere consumers look — sliced G-code (Preview) and source models (Prepare), like a slicer's two modes: - Feature Lab (tools/demo): a Preview/Prepare header toggle swaps the toolpath viewer for a source-model viewer (lazy createModelPreviewController on #modelView), a Prepare tab + "Source model" panel (objects/placements/materials tier/plates), fixtures swap to the model set, camera presets route to the active viewer. - Vue / Svelte / Web Component showcases: the same Preview/Prepare toggle via each framework's <ModelViewer> adapter, mirroring the React reference (built by subagents; reviewed + verified). Fixed a Svelte var collision (the color-mode item was named `mode`, clobbering the workflow `mode` → Prepare never activated; renamed to colorModeItem). - Minimal model page per framework (model.html + a tiny <ModelViewer source> file), linked from each landing as a third tier — a discoverable smallest model integration. - demo-kit: models.js already added (synthetic STL + colored 3MF fixtures). Verified headless across all five surfaces: Prepare loads the colored 3MF (3 objects, materials KNOWN) and toggles back to Preview (454 seg / 14 layers) cleanly; minimals load the STL (1 object, materials unavailable). All builds clean, zero console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-031) Both had a `display` rule that beat the UA [hidden] rule, so in Prepare the Feature Lab still showed the toolpath "N segments / M layers" count pill (misleading beside a source model) and the layers/segments/time scrub strip (inert for a model). Add [hidden] guards + hide the scrub strip on mode switch. The rail "Source model" panel already carries the model's object/placement/materials info. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- adapters.md: new "Two viewers: Preview and Prepare" section (the two halves of the SDK, the /model subpath, per-framework import table); examples note the model tier; <gcode-model-viewer> tag noted. - 4 adapter READMEs: a "Model viewing (Prepare side)" section each (framework import + minimal example + honest materials-tier note + pointer to model.html); model-renderer README documents createModelPreviewController + the /testing suite. - CLAUDE.md parity check: covers both viewer surfaces + the model parity guard. - VISUAL_FEATURE_COVERAGE.md: interactive model viewer now demonstrated everywhere; new model-adapter row; DD-031 delta records the Prepare integration. - changeset: model-renderer + 4 adapters minor (createModelPreviewController + /model subpaths); additive, toolpath-only consumers don't pull the model renderer. docs:links OK (250). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…itest (DD-031) CI's test:packages runs the adapter suites against sibling workspaces resolved from SOURCE via vitest aliases (no built dist required) — the model behavioral suite broke that by importing @chestnutlabs/gcode-model-renderer/testing, which only resolved from built dist locally. Add source aliases for gcode-model-renderer, its /testing subpath, and its transitive gcode-containers to all four adapter vitest configs, matching the existing gcode-preview-core/testing aliasing. Verified: with packages/gcode-model-renderer/dist removed, the model behavioral suite still passes via source. All four adapter suites green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…del adapters (DD-031) Address the defects the release gate surfaced on the model-adapter work: - consumer-vue fixture: add gcode-model-renderer to the pack/build list + fixture deps and regenerate the lockfile — the Vue package's new dependency was unresolvable (its dist was never built in the fixture, and its transitive @ChestnutLabs deps resolved from the registry instead of the local tarballs, breaking the D3 reproducibility guard). - pack-check: regenerate snapshots for the new model dist files (model-preview, model-testing, and each adapter's dist/model/*), and add the raw ./model/ModelViewer.svelte entrypoint to the documented attw exclusion (same reason as ./GcodePreview.svelte — consumer-compiled, attw can't model it). - prettier: format the model-adapter + demo/example files. Full local gate sweep green: lint, typeCheck, build, test (292), test:packages, test:consumer-vue, pack:check, license:check, docs:links. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…CI run (DD-031) The feature branch's first CI run flagged dormant issues: - tools/pack-check.mjs: prettier formatting of the edited attw exclusion. - tools/demo/src/main.js: drop the now-unused `bytes` import and `$` helper. - capture.test.ts: annotate the intentional definite-assignment forward reference (prefer-const) that the stub↔renderer construction cycle requires. Full lint green (0 errors). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(DD-031): consumer UX + framework parity + source-model adapter family
* release: version packages (lockstep) * docs: fold v0.20.0 release notes + resolve the release review - docs/README "Current state" leads with v0.20.0 (source-model viewing as a first-class declarative half of the SDK + toolpath dark-capability closure + Feature Lab + two-tier examples, DD-031); v0.19.0 demoted to Prior. Release-history line appended. - RELEASE_REVIEW.md: all seven changed packages reviewed; Product/Docs/Visual markers resolved, with reconciliation notes (incl. the deferred app-UI media + the two-surface parity coverage). RELEASE_NOTES_DRAFT.md folded in and removed. docs:release-check PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Nathaniel Chestnut <sobechestnut-dev@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
sobechestnut-dev
temporarily deployed
to
github-pages
August 30, 2026 21:43 — with
GitHub Actions
Inactive
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotion of the versioned v0.20.0 state (dev → main) for the lockstep release.
Headline (DD-031): interactive source-model viewing (STL/3MF) becomes a first-class, declarative half of the SDK —
createModelPreviewController+ a<ModelViewer>adapter on each framework's/modelsubpath (<gcode-model-viewer>for the Web Component), with a portable model behavioral suite + parity guards. Plus the toolpath dark-capability closure (getRenderStats/pickSegment/isColorModeAvailable/declarativehiddenFeatureRoles/handlecapture),capture({ includeBuildVolume }), the Feature Lab demo, and two-tier framework examples.All 14 packages bump to v0.20.0 (lockstep). Changesets consumed, per-package CHANGELOGs generated, internal ranges pinned, docs folded (
docs/READMEcurrent-state + release history), andRELEASE_REVIEW.mdresolved.docs:release-checkpasses.Tagging
v0.20.0onmainafter merge triggers the publish workflow.🤖 Generated with Claude Code