Skip to content

release: version packages (lockstep) - #249

Merged
sobechestnut-dev merged 2 commits into
devfrom
changeset-release/dev
Jul 31, 2026
Merged

release: version packages (lockstep)#249
sobechestnut-dev merged 2 commits into
devfrom
changeset-release/dev

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to dev, this PR will be updated.

Releases

@chestnutlabs/gcode-colors@0.4.0

Minor Changes

  • #254 5f59b77 Thanks @sobechestnut-dev! - feat: non-extrusion color modes — color-by-power + cut-vs-rapid (DD-012 phase 4, #189)

    Two new ColorModes consuming the #189 channels (DD-012 D7):

    • power — ramps each segment's modal toolPower (laser power / spindle RPM, the S value) onto
      a color ramp, the CNC/laser counterpart to color-by-speed. Auto-ranged (toolPowerRange) or explicit;
      NaN (tool off) or a file parsed without the toolPower channel → fallback, never a fabricated color.
      Capability-gated on toolPower (the Three renderer's isColorModeAvailable gates it).
    • moveKind — cut-vs-rapid: productive moves (Extrude or Cut) vs rapids (Travel) — the
      "where the tool is actually working" view. Reads the always-present kind channel, so it is always
      available.

    Both flow through createSegmentColorer, so the Three and Canvas-2D renderers get them for free. FDM
    coloring is unchanged.

Patch Changes

  • Updated dependencies [1029580, 8fec7c3]:
    • @chestnutlabs/toolpath-core@0.4.0

@chestnutlabs/gcode-dialects@0.4.0

Minor Changes

  • #258 3f06e5b Thanks @sobechestnut-dev! - feat: evidence-based non-extrusion detection — recognize header-less real CNC/laser files (#189)

    The phase-3 CNC/laser detectors were tuned on synthetic fixtures and matched none of the real
    public samples (LaserGRBL, LinuxCNC, GRBL CAM output) — real controller output usually has no
    generator header
    and writes commands mid-line and concatenated (s3400 m3, g1z-.1).

    Detection is now evidence-scored, not banner-only:

    • A shared scoreEvidence extractor strips comments (so (M3) / ; LinuxCNC in a comment can't
      create a false marker) and matches commands as words anywhere on a line.
    • GRBL laser — LightBurn / $32=1, or the header-less form: a tool-on command (M3/M4) with
      S power and no Z-plunge (lasers are planar).
    • GRBL / generic millM3 spindle that plunges into negative Z with no extrusion (a milling
      fingerprint that separates it from a planar laser); banner optional.
    • LinuxCNC — explicit header, or RS274NGC O-word subroutines/flow (o100 sub).
    • Extrusion detection tightened to E on a motion line, so LinuxCNC M67 E0 Q… analog laser power
      is no longer mistaken for FDM.

    Real-file result: 0/6 → 3/6 detected, each with the correct machine class (laser→laser, mill→mill,
    LinuxCNC→linuxcnc); the misses are honest — files with a commented-out or absent spindle carry no
    tool-state to infer. Still experimental tier (claims reported inferred) — detection working on
    real files is one input; semantic ground truth (does our Cut = actual cutting, S scale) still wants
    a real machine or a trusted reference.

  • #253 13fd5c6 Thanks @sobechestnut-dev! - feat: non-extrusion dialect families + validation tiers (DD-012 phase 3, #189)

    Adds controller detection and the validation-tier honesty mechanism for CNC/laser toolpaths:

    • New dialects (@chestnutlabs/gcode-dialects): GRBL laser (LightBurn / $32 laser mode / M4+S),
      GRBL mill and LinuxCNC (M3 spindle, %/banner envelopes). Registered in the batteries worker.
    • Each dialect adds provenance (cnc.controller, cnc.machineClass, cnc.toolPowerLabel) and a
      validation tier (cnc.validationTier). Per DD-012 D6: an experimental dialect reports its
      non-extrusion claims (cutMoves / toolPower / cannedCycles) as inferred (never known),
      with a cnc-dialect-experimental disclosure — and only for claims the file actually made (an unused
      feature is never fabricated).
    • All launch dialects ship experimental (synthetic fixtures only). A single tier: 'validated'
      flip per controller promotes its claims to known once confirmed on real hardware (DD-012 §8/§15).

    Geometry is untouched (dialects only annotate/label). FDM detection is unaffected — CNC dialects do
    not match FDM output.

  • #262 3e244ae Thanks @sobechestnut-dev! - feat(dialects): promote grbl-laser experimental → validated on hardware evidence (#189)

    First hardware-validation pass (DD-012 D8): a real GRBL/LightBurn diode-laser run — 6161 moves incl.
    fill + offset-fill, full 0–1000 S power ramp — confirmed machine-class detection, the Cut-vs-rapid
    split, and the toolPower channel against the physical cut (all claims ✓). grbl-laser is flipped
    experimental → validated: for laser files its cutMoves/toolPower claims now report known
    instead of inferred, and the cnc-dialect-experimental warning is no longer emitted.

    Scope is per-controller: grbl-mill and linuxcnc remain experimental (claims stay inferred)
    until a run on real CNC hardware. Evidence recorded in docs/design/DD-012-hardware-validation-log.md.

Patch Changes

  • Updated dependencies [1029580, 8fec7c3]:
    • @chestnutlabs/toolpath-core@0.4.0

@chestnutlabs/gcode-parser@0.4.0

Minor Changes

  • #252 b2053be Thanks @sobechestnut-dev! - feat: canned drilling cycle expansion — G81/G82/G83 (DD-012 phase 2, #189)

    CNC canned drilling cycles previously produced zero geometry — holes vanished. They now expand to
    explicit sub-moves so the drilling is real, classified toolpath:

    • G81/G82 (drill / drill-with-dwell): rapid to the hole XY, rapid down to the R plane, feed to
      depth (Cut)
      , rapid retract.
    • G83 (peck): the plunge is a peck loop — feed down by Q, rapid-retract to R between pecks, until
      reaching depth; each down-feed is a Cut.
    • G98/G99 set the retract plane (initial Z vs R); G80 cancels; a G0G3 motion also cancels.
    • Modal repeat: with a cycle active, a bare X/Y line drills another hole (retaining Z/R/Q and
      the initial plane) — the common CNC hole-pattern form.
    • Rapids are Travel, plunges are Cut; new capability cannedCycles (known once a cycle is
      seen, else unavailable).

    FDM output is unchanged (no canned cycles in FDM); the native-golden corpus gains only the additive
    cannedCycles capability, with no geometry change.

  • #253 13fd5c6 Thanks @sobechestnut-dev! - feat: non-extrusion dialect families + validation tiers (DD-012 phase 3, #189)

    Adds controller detection and the validation-tier honesty mechanism for CNC/laser toolpaths:

    • New dialects (@chestnutlabs/gcode-dialects): GRBL laser (LightBurn / $32 laser mode / M4+S),
      GRBL mill and LinuxCNC (M3 spindle, %/banner envelopes). Registered in the batteries worker.
    • Each dialect adds provenance (cnc.controller, cnc.machineClass, cnc.toolPowerLabel) and a
      validation tier (cnc.validationTier). Per DD-012 D6: an experimental dialect reports its
      non-extrusion claims (cutMoves / toolPower / cannedCycles) as inferred (never known),
      with a cnc-dialect-experimental disclosure — and only for claims the file actually made (an unused
      feature is never fabricated).
    • All launch dialects ship experimental (synthetic fixtures only). A single tier: 'validated'
      flip per controller promotes its claims to known once confirmed on real hardware (DD-012 §8/§15).

    Geometry is untouched (dialects only annotate/label). FDM detection is unaffected — CNC dialects do
    not match FDM output.

  • #248 1029580 Thanks @sobechestnut-dev! - feat: non-extrusion Cut move classification + tool-state modal (DD-012 phase 1, #189)

    Non-extrusion toolpaths (CNC / laser / plotter) no longer collapse their productive moves into
    Travel. The parser now tracks a tool-engaged modal state — M3/M4 (spindle/laser on, incl. the
    M03/M04 leading-zero form) engage it, M5 disengages — and classifies a move with no extrusion
    E
    while the tool is engaged as the new MoveKind.Cut bit (a CNC/laser/plotter counterpart to
    Extrude, composing with ArcSegment like the other kinds).

    • New IR move kind MoveKind.Cut = 1 << 7 (@chestnutlabs/toolpath-core).
    • New capability cutMoves: known once a tool-state modal is seen (a CNC/laser/plotter file),
      unavailable for FDM.
    • FDM is byte-identical: FDM slices never issue M3/M4, so Cut is never set and every move
      stays Extrude/Travel exactly as before (verified against the native-golden corpus; the CNC
      fixtures demo-easel/demo-mach3 are documented intentional adapter-divergences).

    Modal tool-state value channels (laser power / spindle RPM via S), canned-cycle expansion, and
    dialect families follow in later DD-012 phases.

  • #251 11f317d Thanks @sobechestnut-dev! - feat: modal motion continuation — bare coordinate lines repeat the last G0–G3 (DD-012 phase 2, #189)

    CNC/LinuxCNC-style G-code frequently omits the G word on repeated moves (G1 X0 Y0 then bare
    X10 Y0 / X20 Y0). The parser previously dropped those lines entirely — a three-move path
    produced a single segment. It now tracks the active G0G3 motion mode and treats a line whose
    leading word is a coordinate axis (X/Y/Z, with no G/M/T command) as a continuation of
    that mode, so the full toolpath is emitted and classified/colored consistently (incl. inline S
    for toolPower).

    FDM output is byte-identical — slicers always emit the G word, so the continuation path never
    triggers (the native-golden corpus is unchanged). This unblocks canned-cycle repeat (next phase).

  • #250 8fec7c3 Thanks @sobechestnut-dev! - feat: opt-in modal tool-power channel (DD-012 phase 1 — the ModalChannel mechanism, #189)

    Adds the shared, opt-in ModalChannel mechanism DD-012 D3 is built around, and its first channel:
    toolPower — the modal spindle/laser S value while a tool is engaged.

    • ParseOptions.modalChannels?: readonly string[] — request per-segment modal channels by id.
      Supported id: 'toolPower'. Unknown ids are ignored with a modal-channel-unsupported warning.
    • ToolpathSegments.modal?: Readonly<Record<string, Float32Array>> — one Float32 column per requested
      channel, present only when requested. An unset value is NaN (an honest "no value here"), never
      a fabricated 0. toolPower is the modal S (set on M3/M4 and inline on GRBL-laser motion
      lines) while engaged, NaN when the tool is off (M5).
    • New capability toolPower: surfaced only when the channel is requested — known once a
      tool-state modal is seen, else unavailable.
    • Default parse pays nothing: no modalChannels ⇒ no modal on the IR, no extra columns, FDM
      output unchanged. The budget-aware SoA writer (DD-003) grows the opt-in columns in lockstep and
      accounts their bytes.

    Presentation (Watts vs RPM) is a dialect label, not a separate channel (DD-012 D4); #180's
    fan/temp/accel color channels reuse this same mechanism in a later phase.

  • #256 b84bea9 Thanks @sobechestnut-dev! - feat: lexer handles multi-command lines, N-word line numbers, and bare S/F (#189)

    Real CNC/laser G-code (GRBL, LinuxCNC, TinyG, Mach3, Fanuc) is written very differently from FDM
    slicer output, and the inherited first-word lexer silently dropped most of it. The lexer now:

    • Reads every G/M/T command word on a line, not just the first — G20 G17 G90, G91 G81 …,
      S3400 M3 now all apply. This was the biggest gap: M3 spindle-on and G81 canned cycles were
      being dropped as params, so mills showed no Cut moves and drilled holes vanished.
    • Strips N-word line numbers (N10 G1 X…) — Fanuc/Mach/TinyG number every line, which
      previously reduced whole files to zero geometry.
    • Latches bare S / F lines (standalone S1000 / F600) into modal power/feed — common in
      GRBL-laser output.
    • Guards against letters embedded in extended-command words (EXCLUDE_OBJECT … POLYGON=…): a
      command/param is only taken when a real number follows the letter, so T in M486 T<count> /
      M104 T<tool> stays a parameter (not a tool select), and the G in POLYGON never becomes a move.

    Validated against real public sample files: a LinuxCNC arc-spiral went from 16 → 5,506 parsed
    segments, a TinyG program from 0 → 344. FDM output is byte-identical — slicers emit one clean
    command per line, so the multi-command path never runs for them (the real-G-code native-golden corpus
    is unchanged except for fewer spurious unsupported-command warnings; demo-mach3 and one adversarial
    binary fixture are documented intentional divergences).

Patch Changes

  • #260 879b60a Thanks @sobechestnut-dev! - fix: G0 rapids classify as Travel, not Cut, even while the tool is engaged (#189)

    The non-extrusion Cut/Travel classifier keyed only on tool-state (M3/M4 latched), so on a
    router — where the spindle stays on across rapids — every G0 reposition was counted as a cutting
    move. DD-012 D2 §4.2 already specifies that rapids stay Travel; this brings the implementation in
    line: only a feed move (G1/G2/G3) with the tool engaged and no E delta is Cut; a G0
    rapid is Travel regardless of tool state (a GRBL-laser also gates the beam off during G0).

    Surfaced by the CNC/laser validation harness on real files — e.g. the easel router fixture went
    from 742 cut / 0 rapids to a correct 737 cut / 5 rapids (its 5 G0 moves). Geometry is unchanged
    (only the kind column shifts); FDM output is byte-identical since Cut is never evaluated there.

  • Updated dependencies [3f06e5b, 13fd5c6, 1029580, 8fec7c3, 3e244ae]:

    • @chestnutlabs/gcode-dialects@0.4.0
    • @chestnutlabs/toolpath-core@0.4.0
    • @chestnutlabs/gcode-bgcode@0.4.0
    • @chestnutlabs/gcode-containers@0.4.0

@chestnutlabs/gcode-renderer-three@0.4.0

Minor Changes

  • #254 5f59b77 Thanks @sobechestnut-dev! - feat: non-extrusion color modes — color-by-power + cut-vs-rapid (DD-012 phase 4, #189)

    Two new ColorModes consuming the #189 channels (DD-012 D7):

    • power — ramps each segment's modal toolPower (laser power / spindle RPM, the S value) onto
      a color ramp, the CNC/laser counterpart to color-by-speed. Auto-ranged (toolPowerRange) or explicit;
      NaN (tool off) or a file parsed without the toolPower channel → fallback, never a fabricated color.
      Capability-gated on toolPower (the Three renderer's isColorModeAvailable gates it).
    • moveKind — cut-vs-rapid: productive moves (Extrude or Cut) vs rapids (Travel) — the
      "where the tool is actually working" view. Reads the always-present kind channel, so it is always
      available.

    Both flow through createSegmentColorer, so the Three and Canvas-2D renderers get them for free. FDM
    coloring is unchanged.

Patch Changes

  • Updated dependencies [5f59b77, 1029580, 8fec7c3]:
    • @chestnutlabs/gcode-colors@0.4.0
    • @chestnutlabs/toolpath-core@0.4.0

@chestnutlabs/toolpath-core@0.4.0

Minor Changes

  • #248 1029580 Thanks @sobechestnut-dev! - feat: non-extrusion Cut move classification + tool-state modal (DD-012 phase 1, #189)

    Non-extrusion toolpaths (CNC / laser / plotter) no longer collapse their productive moves into
    Travel. The parser now tracks a tool-engaged modal state — M3/M4 (spindle/laser on, incl. the
    M03/M04 leading-zero form) engage it, M5 disengages — and classifies a move with no extrusion
    E
    while the tool is engaged as the new MoveKind.Cut bit (a CNC/laser/plotter counterpart to
    Extrude, composing with ArcSegment like the other kinds).

    • New IR move kind MoveKind.Cut = 1 << 7 (@chestnutlabs/toolpath-core).
    • New capability cutMoves: known once a tool-state modal is seen (a CNC/laser/plotter file),
      unavailable for FDM.
    • FDM is byte-identical: FDM slices never issue M3/M4, so Cut is never set and every move
      stays Extrude/Travel exactly as before (verified against the native-golden corpus; the CNC
      fixtures demo-easel/demo-mach3 are documented intentional adapter-divergences).

    Modal tool-state value channels (laser power / spindle RPM via S), canned-cycle expansion, and
    dialect families follow in later DD-012 phases.

  • #250 8fec7c3 Thanks @sobechestnut-dev! - feat: opt-in modal tool-power channel (DD-012 phase 1 — the ModalChannel mechanism, #189)

    Adds the shared, opt-in ModalChannel mechanism DD-012 D3 is built around, and its first channel:
    toolPower — the modal spindle/laser S value while a tool is engaged.

    • ParseOptions.modalChannels?: readonly string[] — request per-segment modal channels by id.
      Supported id: 'toolPower'. Unknown ids are ignored with a modal-channel-unsupported warning.
    • ToolpathSegments.modal?: Readonly<Record<string, Float32Array>> — one Float32 column per requested
      channel, present only when requested. An unset value is NaN (an honest "no value here"), never
      a fabricated 0. toolPower is the modal S (set on M3/M4 and inline on GRBL-laser motion
      lines) while engaged, NaN when the tool is off (M5).
    • New capability toolPower: surfaced only when the channel is requested — known once a
      tool-state modal is seen, else unavailable.
    • Default parse pays nothing: no modalChannels ⇒ no modal on the IR, no extra columns, FDM
      output unchanged. The budget-aware SoA writer (DD-003) grows the opt-in columns in lockstep and
      accounts their bytes.

    Presentation (Watts vs RPM) is a dialect label, not a separate channel (DD-012 D4); #180's
    fan/temp/accel color channels reuse this same mechanism in a later phase.

@chestnutlabs/gcode-bgcode@0.4.0

Patch Changes

  • Updated dependencies [1029580, 8fec7c3]:
    • @chestnutlabs/toolpath-core@0.4.0
    • @chestnutlabs/gcode-containers@0.4.0

@chestnutlabs/gcode-containers@0.4.0

Patch Changes

  • Updated dependencies [1029580, 8fec7c3]:
    • @chestnutlabs/toolpath-core@0.4.0

@chestnutlabs/gcode-preview-core@0.4.0

Patch Changes

@chestnutlabs/gcode-preview-element@0.4.0

Patch Changes

@chestnutlabs/gcode-preview-react@0.4.0

Patch Changes

@chestnutlabs/gcode-preview-svelte@0.4.0

Patch Changes

@chestnutlabs/gcode-preview-vue@0.4.0

Patch Changes

@chestnutlabs/gcode-renderer-2d@0.4.0

Patch Changes

  • Updated dependencies [5f59b77, 1029580, 8fec7c3]:
    • @chestnutlabs/gcode-colors@0.4.0
    • @chestnutlabs/toolpath-core@0.4.0

@github-actions
github-actions Bot force-pushed the changeset-release/dev branch 13 times, most recently from 80da7f6 to fe5719d Compare July 30, 2026 05:32
@github-actions
github-actions Bot force-pushed the changeset-release/dev branch from fe5719d to 9865223 Compare July 31, 2026 20:47
@sobechestnut-dev
sobechestnut-dev merged commit 4f48b0f into dev Jul 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant